www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How To Dynamic Web Rendering?

reply Matthew Ong <ongbp yahoo.com> writes:
Hi,

What is the counterpart in D for replacing JSP/ASP/JRuby on Rail or some sort
of dynamic web base development?

How to compile a D code into dll to be used by apache or MS IIS?

How to also code digitally sign the DLL  that was compiled in D?

Matthew Ong
May 12 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
 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.
 How to also code digitally sign the DLL  that was compiled in D?
The same way you sign any other dll/exe.
May 12 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
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.
May 12 2011
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
 Could you share how or show an URL that provide sample code to do
 that in D?
Check out my D api demo: http://arsdnet.net/cgi-bin/apidemo/ Here's the source code (about 50 lines of D) http://arsdnet.net/apidemo.d And the HTML templates it uses: http://arsdnet.net/apidemo-document.html http://arsdnet.net/apidemo-javascript.html The libraries it imports are available here http://arsdnet.net/dcode/ That demo shows something relatively new I made to provide same source access to HTML and Javascript that uses D's reflection to auto-generate almost everything. You can also do more traditional style web apps. Here's a gradient generator written in D: http://arsdnet.net/cgi-bin/gradient?w=100&h=100&c1=ff0000&c2=00ff00&c4=ffff00&t=50 Source: http://arsdnet.net/gradient.d It uses my cgi.d from the dcode folder above. This code has a few features so it isn't the simplest demo, about 150 lines. It makes the png and sends it right out over the web. Hello world with cgi.d looks like this: import arsd.cgi; void main() { auto cgi = new Cgi(); cgi.write("Hello, world!"); cgi.close(); } In all my examples though, I used mixins for main functions instead of writing them directly because the mixin adds try/catch for exceptions and handles the create and close too. This would look like: import arsd.cgi; void run() { cgi.write("Hello, world!"); } mixin GenericMain!run; I also often use my D DOM library in web code too, which you see in the first example. That library is available in my folder too.
 So we use external tool to do that and not a build in one??
Yes, something like signtool.exe from Microsoft works for Windows programs. Generally, if you can do it to a C++ program, you can do it to a D program too.
May 12 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-12 16:45, Adam Ruppe wrote:
 Could you share how or show an URL that provide sample code to do
 that in D?
Check out my D api demo: http://arsdnet.net/cgi-bin/apidemo/ Here's the source code (about 50 lines of D) http://arsdnet.net/apidemo.d And the HTML templates it uses: http://arsdnet.net/apidemo-document.html http://arsdnet.net/apidemo-javascript.html The libraries it imports are available here http://arsdnet.net/dcode/
How is it working out with a static type system, compared to a dynamic, for web development? -- /Jacob Carlborg
May 13 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Jacob Carlborg" <doob me.com> wrote in message 
news:iqilmh$7tk$1 digitalmars.com...
 On 2011-05-12 16:45, Adam Ruppe wrote:
 Could you share how or show an URL that provide sample code to do
 that in D?
Check out my D api demo: http://arsdnet.net/cgi-bin/apidemo/ Here's the source code (about 50 lines of D) http://arsdnet.net/apidemo.d And the HTML templates it uses: http://arsdnet.net/apidemo-document.html http://arsdnet.net/apidemo-javascript.html The libraries it imports are available here http://arsdnet.net/dcode/
How is it working out with a static type system, compared to a dynamic, for web development?
<bias amount="very-large" inflammatory="potentially"> Much better I would imagine, since dynamic type systems suck &donkeyballs;. </bias>
May 13 2011
prev sibling next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 13/05/2011 08:09, Jacob Carlborg wrote:
 On 2011-05-12 16:45, Adam Ruppe wrote:
 Could you share how or show an URL that provide sample code to do
 that in D?
Check out my D api demo: http://arsdnet.net/cgi-bin/apidemo/ Here's the source code (about 50 lines of D) http://arsdnet.net/apidemo.d And the HTML templates it uses: http://arsdnet.net/apidemo-document.html http://arsdnet.net/apidemo-javascript.html The libraries it imports are available here http://arsdnet.net/dcode/
How is it working out with a static type system, compared to a dynamic, for web development?
How many times, while using a dynamically typed language, do you ever change the type of a variable? I've written a fair amount of PHP, and I rarely, if ever want my string to suddenly become an integer (if I do it generally needs validation/conversion anyway). When using my own and others code I frequently see type checks/conversions etc, it just makes the code ugly - with a staticly typed system you remove this overhead. Also, there's the auto keyword, and easily accessible function templates. -- Robert http://octarineparrot.com/
May 13 2011
parent "Nick Sabalausky" <a a.a> writes:
"Robert Clipsham" <robert octarineparrot.com> wrote in message 
news:iqjer9$1mai$1 digitalmars.com...
 On 13/05/2011 08:09, Jacob Carlborg wrote:
 How is it working out with a static type system, compared to a dynamic,
 for web development?
How many times, while using a dynamically typed language, do you ever change the type of a variable? I've written a fair amount of PHP, and I rarely, if ever want my string to suddenly become an integer (if I do it generally needs validation/conversion anyway). When using my own and others code I frequently see type checks/conversions etc, it just makes the code ugly - with a staticly typed system you remove this overhead. Also, there's the auto keyword, and easily accessible function templates.
And templates for when you want a function to accept multiple types, and Variant for the few times when changing a variable's type might actually be useful.
May 13 2011
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Jacob Carlborg wrote:
 How is it working out with a static type system, compared to a
 dynamic, for web development?
It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence. I can't tell you how many times I've made a minor mistake in PHP, Ruby, or Visual Basic and had it slip through to production because the code path was obscure enough to evade testing. Sometimes, something similar does happen in D - to!int("") throws - but, the compiler catches the majority of incompatible changes instantly. If I had int addUser() and change it to User addUser(), I don't have to hunt every instance down myself. Just hit compile and the compiler tells me where the change causes problems. (Rarer than you might think - thanks to auto, a lot of the program is already duck typed in a way. The actual return value name is rarely used.) It also helps documentation to have good types. I often see stuff like this in dynamic language docs: function doSomething(options); What does it return? What options are available? Maybe the text will tell us that options is an associative array. UGH, I hate that! Now, there's even less knowing what's going on. D's documentation is a lot more helpful, and easier to keep up to date. string doSomething(Options options); // not much better yet.... struct Options; int speed; bool strictMode; bool caseSensitive; Ahhh, now I know! Another thing that the static types enable that I don't think is possible with dynamic functions is the automatic forms you see on my link. http://arsdnet.net/cgi-bin/apidemo/get-a-box I didn't write any html for that. The library made it for me. In the source, you can see it's prototype: http://arsdnet.net/apidemo.d Element getABox(Color color); The reflection was able to say "it needs a Color, and there's only a handful of valid Colors - enum Color - so I can automatically create a <select> box for this." Dynamic types for return values can still do most the stuff my api generator does. Whether it's a static function/template toHtml or a dynamic property doesn't matter much. But the parameters... I don't think it can be done without the static types there. (Another nice thing is the library checks the type too. Coming off the request parameters, you have strings; dynamic types. But going into the function, it knows it must be a Color, so it checks. If not, an exception is thrown. By the time you're inside the function, you can be guaranteed that Color color is indeed a Color. Thus, to!string() to insert it into the html attribute that I did here is perfectly safe. It's a whitelist based filter, all done automatically.) There are a few cases where dynamic types are helpful or needed. D lets us opt in to them with only a minimal amount of fuss. The places where I use it are: 1) Data from the user. Form variables are of type string coming into the program. Once decoded, you have string[][string]. Your program probably wants something else. The to!() template in Phobos makes this pretty easy, or if you want default value and get/post combined, my cgi class has a request template: int a = cgi.request!int("a"); That's similar to this in PHP: $a = 0; if(isset($_POST['a'])) $a = (int) $_POST['a']; else if(isset($_GET['a'])) $a = (int) $_GET['a']; PHP is so outrageously verbose. And the PHP is buggy compared to the D... if you do cgi.request!int("a", 10) and the user does a=txt, the PHP result is wrong. It's not quite fair to compare a function to a code collection though. A php function could do it right too. Annnnyway, I'm digressing. Hell, I'm going on about weak types instead of dynamic types! Even in Ruby, you'd have to do a to_i since the url value simply is a string. Back to dynamic types. The three other places where you see them are databases and interfacing with external services. 2) Databases With databases, you probably expect a certain type anyway. If the column is typed as INTEGER, you probably don't want 'lol' in there. But, the database takes care of that for you. In my libs, I just use strings. auto line = mysql.query("SELECT id FROM users WHERE id = 10").front; res[0] == "10" Conversions are now done the same as URL parameters: int id = to!int(res[0]); Oftentimes, I don't really care about it though; if I'm outputting it to html, I'll just say: table.appendRow(res["id"], res["name"]) and the like anyway. You want a string there, so it just works. (appendRow is in fact a variadic template so it'd just work regardless, but you get the idea anyway). Thanks to static checks though, if I were to later change my mind and wanted ints, or made the database return Variants or whatever, no problem - the compiler will point out trouble spots to me. Inserting data is the same: mysql.query("INSERT INTO users (id) VALUES (?)", 10); // works mysql.query("INSERT INTO users (id) VALUES (?)", cgi.post["id"]); // works too Or using the data object class: auto obj = new DataObject(mysql, "users"); obj.id = 10; // works obj.id = "10"; // works just as well obj.commitChanges(); (The DataObject can read too, offering database fields as obj.id style properties. They always return string, just like plain query, but are also read/write.) DataObject can also be specialized automatically to use static types if you like. db.sql: create table users(id integer primary key, name varchar(30)); file.d: // parse out that create table to map the names and types automatically alias DataObjectFromSqlCreateTable!(import("db.sql"), "users") User; User a; a.id = "12"; // type mismatch, fails to compile a.name = "hello"; // works a.nmae = "sad" // typo caught at compile time a.commitChanges(); // otherwise it is still based on DataObject In short, I have the best of both worlds, with the only extra effort being writing to!() here and there and that one line to import the sql definition. 3) HTML I *want* strict typing when working with html in almost all cases. It helps catch encoding bugs. The one place where I want dynamics - fetching an element off the html template - I have it, this time provided through classes. auto table = cast(Table) document.getElementById("data-table"); assert(table !is null); // fails if it isn't a <table> tag // use the table class's special functions Forms, Links, and other types of nodes are handled similarly. The Element base class though does most the simple operations. Being plain old inheritance, the virtual functions act dynamically enough. Of course, if the HTML changes, that assert/enforce will trigger at run time. We're still ahead of dynamic languages though: the compiler will tell me what breaks if I remove the cast, with one exception: I use an opDispatch there for attributes. That will break some functions. Table t = ...; t.caption = "Hello!"; // changes the <caption> tag child Element t = ...; t.caption = "Hello!"; // sets a caption="" attribute But meh, in this case, I like the flexibility of accessing attributes like that. The compiler still catches more than it doesn't - we're still ahead of the mistakes possible in dynamic languages while keeping the convenience. 4) External services This is where dynamic types are the most useful. Accessing Facebook, Twitter, etc., returns xml or json with types that change based on a lot of things. Is the user logged in? What url is it? In this case, it's like the database, but the types tend to be more complex. Simple string cowboying won't cut it. Thankfully, D's Variant is up to the task. Variant userRet = fbGraph(token, "/me"); // we know /me returns a json object from the docs, so fetch it: auto user = userRet.get(Variant[string]); auto name = user["name"].get!string; // name is a string == "Adam D. Ruppe" Not terribly hard. Robert Jacques IIRC has written an improved std.json patch to make this work almost just like Javascript: auto user = fbGraph(token, "/me"); user.name.get!string; // same as above So D's definitely up to the job. The only difference is that final use of get!string. I believe Phobos' to! works as well. In the end, there's nothing web related in my experience that a dynamic language can do that D can't do almost or just as well, and plenty that D and it's static types can do that dynamic types can't do, or require piles of painful tests and manually written code or documentation to do. D kicks the Web's ass. (And my web related libraries go even further than seen here. My custom DOM offers a lot of things that are way cool, enabling new CSS stuff, filling forms easily, in about 1/10 the code of doing it similarly in PHP, and without mucking up the HTML. The web api/site generator makes D accessible through urls, forms, javascript - view the source here for a glimpse of that lib: http://arsdnet.net/cgi-bin/apidemo/javascript 20 kb of javascript, including the auto generated API bindings! And more stuff is packed in there too. Best of all: D, through CGI, consistently does well or better than mod_php in my speed benchmarks. I've barely tried to optimize too; there's a lot of untapped potential. If your host doesn't suck, dive into D on the web. You won't want to go back.)
May 13 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:iqji6m$1se1$1 digitalmars.com...
 Jacob Carlborg wrote:
 How is it working out with a static type system, compared to a
 dynamic, for web development?
It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence. I can't tell you how many times I've made a minor mistake in PHP, Ruby, or Visual Basic and had it slip through to production because the code path was obscure enough to evade testing.
Yea, it all just comes from dynamic being sloppy and overly-permissive. Before I switched my web development to Haxe (not remotely as good as D, but it beats the hell out of straight PHP/ActionScript), I had to do some stuff in ActionScript2. Anytime anything would go wrong (other than a syntax error), the compiler would accept it, and the *runtime* would accept it and just simply ignore it and move on. Not even an exception or log notice or anything. That alone turned development into an absolute nightmare. Nothing ever worked, you never had the slightest clue why, and it took forever to track the problem down to something that, invariably, would turn out to be something D would have caught immediately, usually at compile-time. And that was all in the name of being "forgiving". Blech. Bottom line, whether dynamically-typing or anything else: being overly-permissive sucks. What D permits you to do is tighten the damn leash.
 The to!() template in Phobos makes this pretty easy, or if you
 want default value and get/post combined, my cgi class has a request
 template:
to!() is absolutely awesome. OTOH, thanks to to!(), the conversion functions in every other language out there seem irritatingly poorly designed. ;) Anytime I have to do a conversion in Haxe, I always end up needing to reach for the std API reference. And even Haxe's API for conversions is pretty good compared to some other langauges.
 int a = cgi.request!int("a");

 That's similar to this in PHP:

 $a = 0;
 if(isset($_POST['a']))
  $a = (int) $_POST['a'];
 else
 if(isset($_GET['a']))
  $a = (int) $_GET['a'];


 PHP is so outrageously verbose. And the PHP is buggy compared to
 the D... if you do cgi.request!int("a", 10) and the user does a=txt,
 the PHP result is wrong. It's not quite fair to compare a function
 to a code collection though. A php function could do it right too.
Be glad it's not VB6, or worse, VBScript. I've had to do a lot of web dev in those languages in the past, and as horrible as PHP is overall, for outright verbosity it doesn't even compare to VB6/VBScript. auto myVar = "foo"; $myVar = "foo"; vs: Dim myVar As String myVar = "foo" Seriously?! And don't get me started on VB's million-and-one different things you have to check for to see whether or not a string actually contains anything. And then there's its arrays, which wouldn't be *too* bad if they didn't allow the staring index to be chosen completely at random. So, wanna find the length of an array? In D it's: myArray.length In PHP it's probably about the same as D. In VBScript, if you want to do it correctly, it's: (UBound(myArray) - LBound(myArray))+1 Or you can do UBound(myArray)+1 and just pray that some stupid jackass doesn't actually try to use the "choose your array's lower bound", ahem, "feature". I can just feel my sanity fading...
 auto table = cast(Table) document.getElementById("data-table");
 assert(table !is null); // fails if it isn't a <table> tag

 // use the table class's special functions


 Forms, Links, and other types of nodes are handled similarly. The
 Element base class though does most the simple operations. Being
 plain old inheritance, the virtual functions act dynamically
 enough.
You know, I used to absolutely love doing the rails-like thing of using HTML templates. And Terence Parr's StringTemplate even managed to convince me for awhile that such templates shouldn't have imperative logic. But the more I watch your DOM approach and then continue using HTML templates (very mercifully, one that thankfully *does* allow imperative logic), the more fed up I'm starting to get with the template approach. Granted, I haven't used it yet, but I think you've got the right approach with your DOM stuff.
 And more stuff is packed in there too. Best of all: D, through
 CGI, consistently does well or better than mod_php in my speed
 benchmarks. I've barely tried to optimize too; there's a lot of
 untapped potential.
One of the things I've noticed never even seems to get mentioned is that even though CGI has had a stigma of high startup costs, *MANY* php installations, even on commercial shared hosting, have php set up to run as CGI. So even if php interpretation wasn't much slower than good compiled code, it *still* wouldn't usually have the speed advantage people have attributed to it.
 If your host doesn't suck, dive into D on the web. You won't want
 to go back.)
Won't want to go back to dynamic web scripting? Hell, I haven't even done any D CGI beyond a trivial hello world (for which I had to jump through *enormous* hoops to get working with my damn shared web hosts - and one of them, turns out, won't even support compiled CGI at all), and yet, I just plain don't want to *remain* with dynamic web scripting. :) Another thing, too, that's really good about D being faster is that you can do a lot more before Apache/PHP/whatever decides to kill you off for taking too long. And you can realistically try to anticipate it, finish up any atomic operations, and die gracefully instead of risking corruption from broken atomicity. That's getting to be a problem in my Haxe/PHP stuff. I have my code set up so that when there's an unhandled exception, it automatically tries to log it to three separate places: a logfile, the DB, and email. (And if any one of those fails, it still attempts the others and then tries to notify the others that the one failed. I'm really proud of the whole system :)) And, of course, a stack trace is included. But the problem is, this all takes (noticable) time, especially on PHP, so I risk loosing all the info that anything even went wrong at all just because the server killed it off for taking too long. And that's actually happened a few times on my local dev system (I *hope* it hasn't happened on the server...) Heck, I can usually tell when it's crashed even before I get the error page just because it'll take noticably longer than usual. But what makes all that really bad is there seems to be a bug in either Haxe or PHP that causes stack traces to include *all* the functions called...ie, even the ones that have returned, instead of just the current call stack. So the *ahem* "call stack" ends up huge (and hard to use). And there's two things that make it far bigger than it even needs to be: 1. There's a big data structure I sometimes need (data that doesn't actually change - so it's converted automatically at build-time from a raw datafile to a direct hard-coded Haxe source file). But Haxe, and presumably PHP, doesn't allow compex literals. And even if it did, there's no such thing as pre-compiled PHP, so there's no such thing as a statically-initialized data segment. So the generated Haxe code has to actually build up the data structure at runtime. And the structure is somewhat large...and there's a limit on function size (don't recall if it's a Haxe or PHP limit)...so each piece of the data-building has to be put into it's own function. And there's currently hundreds of these little functions. So that makes the "broken stack trace" that much bigger and slower to build. 2. Haxe has runtime reflection, which is needed for it's, rather good, object database API. But the reflection works by keeping the info stored as...get this...XML...and then the XML is parsed to retrieve the actual data. Which is incredibly stupid, of course, but that's how it's done. And, of course, there's recursion involved in that XML parsing, so that bloats the big slow broken stack trace even more. Although, all that reminds me, servers (especially shared hosts) can also have memory limits on scripts and CGI. But D's GC likes to just keep grabbing system RAM and only release back to the OS when really necessary, or when you tell it to. And even that can be blocked by false pointers. Have you had any problems with server memory caps and D's memory behavior?
May 13 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Nick Sabalausky wrote:
 Be glad it's not VB6, or worse, VBScript.
Oh, I know it! One of my side jobs I picked up this year is maintaining somd old VBS program, using classic ASP. There's so much nonsense. It doesn't help that the original author was horribly incompetent - he never used functions/subs, just copy and pasted everything. Over and over and over again. (And to make it worse, the authors apparently didn't know HTML. Not a single standard link or form. *everything* is done as javascript or client side vbscript - mixed at random - calls in href attrs.) My biggest problem when writing code for them though is that I instinctively put semicolons at the end of thoughts....
 CGI has had a stigma of high startup costs
I'm now convinced almost all of CGI's bad reputation is actually Perl's problems that got misattributed. Starting a process is quite fast. Starting a process, reading a script, compiling it, and interpreting it... that's kinda slow. Moreover, Linux used to be slower at forking new processes than it is today, so improvements to the kernel help today too. While my own benchmarks have shown a difference between mod_php and cgi hello world.... those differences disappear once you start using it on a real network. The slowdown of cgi is nothing next to even a fast network ping. Now, none of the sites I've worked on have had millions of users. Maybe the tiny difference adds up. I doubt it, but I can't prove it. But, let's face it. Virtually none of us have millions of users anyway. And if I did, I'm sure I can spare a few days to profile and fix the problem (either moving to persistent processes, or profiling Apache or whatever) in between my cash showers and golden baths. There's nothing inheriently slow about a D web site - quite the opposite, actually.
 Have you had any problems with server memory caps and D's memory
 behavior?
No, but at the same time, I don't process huge datasets yet abd run most everything on servers I have root on. (there is a portion that runs on a shared host and my D does work there, it has very light duties so I don't know what would happen if it hit the limit.) CGI programs tend to be fairly short lived though, so the GC might not be necessary at all. Once the request is complete, the process terminates, releasing everything at once.
May 13 2011
parent "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:iqkbm3$8gc$1 digitalmars.com...
 Nick Sabalausky wrote:
 Be glad it's not VB6, or worse, VBScript.
Oh, I know it! One of my side jobs I picked up this year is maintaining somd old VBS program, using classic ASP. There's so much nonsense. It doesn't help that the original author was horribly incompetent - he never used functions/subs, just copy and pasted everything. Over and over and over again. (And to make it worse, the authors apparently didn't know HTML. Not a single standard link or form. *everything* is done as javascript or client side vbscript - mixed at random - calls in href attrs.)
Ouch. I've been to sites that couldn't figure out how to make a link without JS. It gives you the same sort of feeling as watching a perfectly healthy grown adult be unable to...I dunno, insert anything blatantly obvious that most toddlers have mastered here. ;)
 My biggest problem when writing code for them though is that I
 instinctively put semicolons at the end of thoughts....
Heh, I have the exact same problem anytime I use a no-semicolon language. :)
 CGI has had a stigma of high startup costs
I'm now convinced almost all of CGI's bad reputation is actually Perl's problems that got misattributed.
Yea, I don't that. Especially since I've started noticing at least one shared web host that took "CGI" to mean "Perl and Python".
May 14 2011
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
 I haven't used it yet, but I think you've got the right approach
 with your DOM stuff.
For people who haven't read about this, I just wrote up a quick document about it: http://arsdnet.net/web.d/dom.html I really rambled at points, but I wanted to cover all the bases.
May 13 2011
next sibling parent reply albatroz <rmcjustino gmail.com> writes:
This should be also be posted on the Announce list!

I'm considering D for web develoment and your libs provide a nice solution, 
the only issue is until now we would have to dig on this NewsGroup for your 
posts (the big ones), so that we could have an ideia how to use them. 

I would also like to suggest to you if possible, start hosting your scripts 
using a VCS, would be nice to spot your updates and changes.

Any way thank you for sharing your amazing work.

Adam D.  Ruppe wrote:
 For people who haven't read about this, I just wrote up a quick
 document about it:
 
 http://arsdnet.net/web.d/dom.html
 
 I really rambled at points, but I wanted to cover all the bases.
May 14 2011
parent Adam Ruppe <destructionator gmail.com> writes:
Yea, I'm going to start storing or at least linking some of my writings
in that new web.d directory so it will be easier to find.

For a version control system though, blargh, it always feels like
extra work to me. I very rarely use them at all. Most my basic libs
though are pretty stable now. cgi.d and dom.d are both in good shape.
(cgi.d did recently get new cache control functions. I discussed that
in a forum post here: http://www.sveit.com/forum/viewtopic.php?f=25&t=3407

But, the core of it, is pretty much done to me.)

The actual web.d file though - the site/api generator - has been getting
a lot of changes these last couple weeks. It's in a state of rapid
change now since I've started using it on some more projects.


Once that part is solid, I'll write about it in that new folder and
post some links to the announce group.
May 14 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-14 04:17, Adam D. Ruppe wrote:
 I haven't used it yet, but I think you've got the right approach
 with your DOM stuff.
For people who haven't read about this, I just wrote up a quick document about it: http://arsdnet.net/web.d/dom.html I really rambled at points, but I wanted to cover all the bases.
I can agree with some of this but not all of it. I quite like Rails' Model-View-Controller pattern which allows the view layer to contain logic but which you should try to avoid as much as possible. I guess this fall under "PHP (Disciplined)". I don't see anything wrong with the view layer containing simple logic, like this (written in HAML): %ul - posts.each do |post| %li= post.title Or, if you prefer, you can a partial: posts.html.haml: %ul = render posts _post.html.haml: %li= post.title -- /Jacob Carlborg
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Jacob Carlborg wrote:
 I don't see anything wrong with the view layer containing simple
 logic, like this (written in HAML):
I don't think it's bad - I just think it isn't as good as we can get.
May 15 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-15 17:46, Adam D. Ruppe wrote:
 Jacob Carlborg wrote:
 I don't see anything wrong with the view layer containing simple
 logic, like this (written in HAML):
I don't think it's bad - I just think it isn't as good as we can get.
Correct me if I'm wrong but you don't like to have logic in the view layer. Instead you move the view layer into the model or controller layer. How's that any different? -- /Jacob Carlborg
May 16 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
 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.
May 16 2011
parent reply Jacob Carlborg <doob me.com> writes:
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 16 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"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
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"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
parent reply Jacob Carlborg <doob me.com> writes:
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
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent reply "Nick Sabalausky" <a a.a> writes:
"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
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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 17 2011
parent Jacob Carlborg <doob me.com> writes:
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 17 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
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
prev sibling next sibling parent reply Alexander <aldem+dmars nk7.net> writes:
On 13.05.2011 17:19, Adam D. Ruppe wrote:

 It's *much* better, especially for rapid development. The compiler
 will tell me if my changes anywhere break things anywhere else,
 so I can modify with confidence.
Sure, there are many pros. And one significant drawback - it couldn't be easily embedded into HTML code. Either, you have to generate all your pages from inside of CGI script, or use templates - but the main advantage of PHP is that you can mix it with page text. Unfortunately, this is not really possible with D (or C, or C++ etc) - because the code needs to be compiled first, and that could be difficult to do if it is embedded into the page. /Alexander
May 14 2011
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
Alexander wrote:
  Sure, there are many pros. And one significant drawback - it
  couldn't be easily embedded into HTML code.
Two notes: 1) actually, you can. 2) You don't want to. 1) I wrote a little program called dhp.d - write D in a PHP style. http://arsdnet.net/dhp.d About 100 lines of D - not exactly a fancy program - but it shows a way you could do it. Use dhp as an interpreter for your "script". You write html here <?d // D code here ?> // back to html When dhp is run, it compiles the file on the fly. (This implementation doesn't cache, but it could and should) Then, it passes control to the newly compiled file, which runs and outputs your stuff. Literal html outside the <?d ?> tags is passed through just like php. This is implemented by putting quotes around it and cgi.writting it in the generated code. 2) While you could do it, you shouldn't do it. This is bad form even in PHP. See part of my DOM template writeup for a brief on why: http://arsdnet.net/web.d/dom.html Basically, it gets ugly, fast.
May 14 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 14.05.2011 17:13, Adam Ruppe wrote:

 1) I wrote a little program called dhp.d - write D in a PHP style.
Not really a solution. It doesn't work like PHP/ASP do - the result cannot communicate with other pages even if you implement the caching. Basically, you have to implement the whole framework around this, and somehow find a way to share the data etc - which is not so trivial in D right now.
 2) While you could do it, you shouldn't do it. This is bad form even
 in PHP. See part of my DOM template writeup for a brief on why:
 http://arsdnet.net/web.d/dom.html
Sorry, not very convincing. There are many people and many solutions, your is not universal, unfortunately. When I say "not universal" - I mean simply "not everyone will like and use it" (I don't like DOM and XML, for instance - so I try to avoid them as much as possible). Different developers do things in different way, that's why embedding code in web-pages (PHP/ASP way) is (for some people and/or applications, at least) is more preferred or productive.
 Basically, it gets ugly, fast.
Depends on how you do this ;) /Alexander
May 14 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
   Not really a solution. It doesn't work like PHP/ASP do - the result
 cannot communicate with other pages even if you implement the caching.
Can you show me a PHP example showing what you mean? I can't think of anything you can do in PHP that D can't do at least as well. If by communicating with other pages you mean something like php's include(), that's trivial (just include the file here too!)
May 14 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 14.05.2011 23:20, Adam Ruppe wrote:

 Can you show me a PHP example showing what you mean? I can't think
 of anything you can do in PHP that D can't do at least as well.
Something like this: http://core.trac.wordpress.org/browser/trunk/wp-content/themes/twentyten/header.php
 If by communicating with other pages you mean something like php's include(),
that's trivial (just include the file here too!)
No, I mean state/data exchange. Say, somewhere on the page you set a variable, and it's values is visible on all other pages. /Alexander
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
  Say, somewhere on the page you set a variable, and it's values is
 visible on all other pages.
My simple implementation does that. The way it works is say you have this file: === <?d auto title = "hello"; ?> <title><?= title ?></title> === It scans through and turns the stuff outside <??> into string literals and wraps the whole thing in a main function. So that becomes: /* snip imports */ void main() { auto title = "hello"; write("<title>"); write(title); write ("</title>"); } When it runs, you get the result you expect coming from PHP. Thank's to D's nested functions, classes, etc., you can do just about anything with the language, despite it all being inside one big main function once generated. In PHP, pages share data by having one include the other. Even Wordpress templates ultimately work that way - the main code includes the template's code after defining a bunch of functions and variables. If you did the same here, the variables from before would be visible in your scope. auto title = "hello"; write("<title>"); write(title); write ("</title>"); // include a similar file that says <?= replace(title, "h", "H"); ?> write(replace(title, "h", "H"); And it'd work - the title variable hasn't disappeared. There is one thing Wordpress does that would *not* work here though: including a file based on a dynamic variable. include("file.dph"); // works fine - the string can be pulled out // by the preprocessor and compiled include(file-from-user); // wouldn't work You could make it work by providing a pool of available files though, then picking one of them from the list. I only wrote that little program as a toy a while ago. Someone on the newsgroup said it was impossible... I rather like showing the possible in D instead, even if I find it useless. But since I do find it pretty useless, I never finished it. Still, even in it's unfinished state, most of this works already. Sharing data is easy.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 17:04, Adam D. Ruppe wrote:

 In PHP, pages share data by having one include the other. Even
 Wordpress templates ultimately work that way - the main code
 includes the template's code after defining a bunch of functions
 and variables.
This is not what I mean. What I mean is something like: page-a.html: <?d var = "value" ?> page-b.html: <?= var ?> And this I expect to work. Just an example of what I mean, of course. I.e., *all* pages share the same namespace, and all values stored on one page are accessible on all other pages *and* persistent. Sure, we can use database or shared memory to implement persistence - but this will be way too slower comparing to some in-memory state, not talking about complex objects which cannot be stored (easily) in the database. To implement this, you would need a "bit" more than your dhp does (while PHP and ASP provide out of the box). /Alexander
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
 page-a.html:
 <?d var = "value" ?>
 page-b.html:
 <?= var ?>

 And this I expect to work.
That doesn't work in PHP nor ASP. In them, you *must* have page-a include page-b, or a parent page include both, unless you are populating the var from the session (see below). Try it. It's identical to dhp's preprocessor approach.
 *and* persistent.
That never works in PHP nor ASP, not even with php's register_globals. You have to use an explicit session to keep variables around between calls. Note that PHP's register_globals, if you're actually using it, is a huge huge mistake that they've deprecated in new versions.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 18:17, Adam D. Ruppe wrote:

 That doesn't work in PHP nor ASP. In them, you *must* have page-a
 include page-b, or a parent page include both, unless you are
 populating the var from the session (see below).
Don't take my example literally, please - I just wanted to point that there is some globally visible storage accessible to all pages, be it session or something else, but which exists while the server is running and is very fast (i.e. not in DB).
 That never works in PHP nor ASP, not even with php's
 register_globals. You have to use an explicit session to keep
 variables around between calls.
Again - session data s something that is transparently (more or less) accessible to all pages. dhp doesn't do this, as far as I can see. If application is a set of pages, there should be a way to share data between pages without using complicated or expensive persistent storage. /Alexander
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
 If application is a set of pages, there should be a way to share
 data between pages without using complicated or expensive
 persistent storage.
FYI, PHP uses files on the hard drive for sessions by default... optionally, it can use a database too. AFAIK, there is no in-memory option beyond the options the kernel or database provide for file/table caching.
 Again - session data s something that is transparently (more or
 less) accessible to all pages. dhp doesn't do this, as far as I can
 see.
Nope, it'd be provided by an external library. Like I said in another sub-thread, I thought about cloning PHP's approach for a while. (There's a small amount of code to this end still commented out in my cgi.d and phphelpers.d modules) But, I never finished it, because I use sessions so rarely. Most usages of it don't match well with the web's stateless design - if someone opens a link on your site in a new window, can be browse both windows independently? Changing one *usually* shouldn't change the other. The two exceptions are logging in, which barely requires session data at all - matching session id and other identifiers to user id is all that's really necessary. Another big exception is something like a shopping cart. In cases like that, I prefer to use the database to store the cart anyway. So I've had no need for a fancy session system, and thus, never finished mine. It provides some session ID functions, but lets you do whatever you want with it beyond that. I can use them to store temporary files, as keys into the database, whatever. (BTW, PHP's automatic session handling *only* uses the session id. This leaves it open to trivial session hijacking. In web.d, the session functions automatically check IP address and user agent as well as cookies. It can still be hijacked in some places, but it's a little harder. To prevent hijacking in all situations, https is a required part of the solution, and the cgi library can't force that unilaterally. Well, maybe it could, but it'd suck.) I have considered adding a library for some persistent stuff though. One example is a service that pushes updates to clients. (The client uses ajax long polling or something similar to work around the limitations of the web environment.) I've written two programs in D that work like this - a real time web chat server and the more generic (and incomplete) D Windowing System's ajax bridge. But neither one simply broadcasts messages to waiting http clients. This would be useful for doing updates like Facebook. If someone posts a new wall post, it shows up on everyone's browser, pretty quickly. The usage code would look like this: broadcaster.push(channelId, message); The waiting clients run javascript that looks like so: var listener = new Listener("channelId"); listener.messageReceived = function(message) { ... }; Very simple. Maybe I'll write that today. There's two other things a longer running process is good for: 1) Session storage (see, on topic!). You speak a protocol to it... it's basically a reinvention of a database engine using memory tables. Might as well just use a real database engine with in-memory tables, or temporary files, relying on the kernel to keep them in memory. I'm in no rush to write this, since there's little need and existing stuff does it well when you do want it. If you have complex objects, you might want to keep them in memory. In that case, you can just use an embedded http server instead of cgi. My cgi class lets you do this without changing the bulk of your client code, and I've written an embedded http server in D to go with it. 2) Doing work that takes a long time or needs to be scheduled. There's three approaches to this, all of which work today: a) fork() your process, letting the child do the work while the main cgi program finishes. This is very convenient to program: // prepare stuff runInBackground( { // write code here to run, using variables prepared above }); // terminate, not worrying about the background process. It will // live on without you. The downside is I *believe* it doesn't scale to massiveness. Then again, most our sites aren't massive anyway, so does it matter? Also, I'm not sure if it scales or not, since I haven't tried. The most I've actually done using it for real was about 20 concurrent users. It did fine there, but everything does fine for small n. Another downside is communicating with it is hard. Could be solved by adding some message passing functions to the library, or combining it with the persistent notifier service described above. You would have to store it's process ID or the name of a pipe to talk to it though. Also, remember if it is doing work, you don't want to talk to it again. A cross-process lock is probably desired. Such is not handled automatically either. Finally, long running processes can't be updated. You have to kill them and restart, but if their state is only in memory, this means you lose data. Still, it is quite convenient! b) The way most PHP sites do things is to write out work to do later to the database, then depend on a cron job to check it and execute the stored commands. While it still takes care to ensure things are locked, communication is a little easier - instead of talking to the process, you poll the work list in the database. It could also use the persistent notification service. The cron job may be triggered by a lot of things. Page views (ugh), including automatic refreshes (double ugh), a real cron daemon, or user action, such as hitting ok on a schedule screen then doing it in the foreground, or a desktop application. One of my work projects went with the latter. The server cron app was moved to the user's desktops. Thanks to it all being written in a real programming language like D, reusing the code from the server app in a compiled GUI application was no trouble. I imported the same modules and compiled them for distribution. The users didn't have to install an interpreter or an httpd. 3) Use a persistent process in the first place, and run long work in a background thread, or even a foreground thread that isn't killed off by timeouts or disconnections. An embedded http server and std.concurrency can help with this. While all of these are possible, I usually stick with the traditional cron approach. It's simple enough, it's effective, and it's pretty resilient to things like the server going down. The worklist is still in the db so it can be restarted later. wow, I went off at length again.
May 15 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:iqp7gu$7l6$1 digitalmars.com...
 (BTW, PHP's automatic session handling *only* uses the session id.
 This leaves it open to trivial session hijacking. In web.d, the
 session functions automatically check IP address and user agent
 as well as cookies. It can still be hijacked in some places, but
 it's a little harder. To prevent hijacking in all situations,
 https is a required part of the solution, and the cgi library can't
 force that unilaterally. Well, maybe it could, but it'd suck.)
My understanding is that you CANNOT assume different requests in the same session from the same computer are coming from the same IP. Apperently there are a lot of networks, such as corporate networks and anonymizing networks, which will cause different requests from the same user to wind up coming from different IPs. The *ONLY* reliable way to prevent session hijacking without breaking your site for many users is to force everything (and I mean EVERYTHING) through https from the time the session is created to the time the session is killed. Yes, that does suck, but you'll certainly never see me claim that the web isn't the absolute worst, piece of shit excuse for an "applications platform" in history. One of the reasons for this particular mess (besides the whole "shoving applications through a stateless protocol" bullshit) is idiotic limitations of cookies. More specifically, there isn't nearly enough you can do to restrict the URLs for which the browser will send a particular cookie.
May 15 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
 My understanding is that you CANNOT assume different requests in
 the same session from the same computer are coming from the same IP.
Yea, I've heard of that, but it seems to work. phpBB has an option to only check some of the IP, which would probably work even better. Worst case is if I get a bug report from someone saying "I can't log in" and it not just that the user forgot his password... it's a trivially easy change to make.
May 15 2011
prev sibling parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 20:54, Adam D. Ruppe wrote:

 FYI, PHP uses files on the hard drive for sessions by default...
 optionally, it can use a database too.
Not really. There are different options to keep the session data, though - so some of them may resort to store something in the disk. Both cases (disk/db) terribly slow down everything. I don't know how many visitors your websites have, but if you have several visits per second - you will feel it.
 AFAIK, there is no in-memory option beyond the options the kernel or database
provide for file/table caching.
There are several, again - like memcache. Believe me, once you have at least 500k page requests/month (excluding images and other static content, of course), you will change your mind about where (and how) to store data.
 But, I never finished it, because I use sessions so rarely. Most
 usages of it don't match well with the web's stateless design -
 if someone opens a link on your site in a new window, can be
 browse both windows independently?
Web is stateless as long as you have static content only. What about web-commerce, shopping, applications like Google AdWords, web-mail etc? How can you handle it? But what do you mean by "independently"? Sure you can browse both, just any changes in session state (like, adding something to shopping cart) will be propagated to all windows eventually.
 Changing one *usually* shouldn't change the other.
Sorry? Do you ever do some shopping online? ;) If I have many windows open, with different items, I *expect* that all of them will go into *one* shopping cart - "usually" :)
 Another big exception is something like a shopping cart. In cases like that, I
prefer to use the database to store the cart anyway.
Ah, here we are. Sure, you will need to store into DB - but only *if* there are changes. For any data which is not changing, but requested quite often, each access to the database will slow things down.
 In web.d, the session functions automatically check IP address and user agent
 as well as cookies. It can still be hijacked in some places, but it's a little
harder.
This is exactly what well-designed application and libraries do.
 To prevent hijacking in all situations, https is a required part of the
solution, and the cgi library can't
 force that unilaterally. Well, maybe it could, but it'd suck.)
It *can* enforce, by refusing non-encrypted connection, or redirecting to https when access is done by http.
 The downside is I *believe* it doesn't scale to massiveness. Then
 again, most our sites aren't massive anyway, so does it matter?
Most of our are massive enough, so - it does matter :)
 Finally, long running processes can't be updated. You have to kill them and
restart, but if their state is only in memory, this means
 you lose data.
Not really - process should flush any dirty data to persistent storage and quit, so new copy may catch on. /Alexander
May 16 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
 I don't know how many visitors your websites have, but if you have
 several visits per second - you will feel it.
views a month. That's actually very rare. The way I do optimizations is I write it just however comes to mind first (which usually isn't half bad, if I do say so myself), then watch it under testing. If it proves to be a problem in real world use, then I'll start watching the times. IE9 has things built in to watch on the client side. D has stuff built in to watch the server side code. I sometimes just sprinkle writefln(timestamp) too for quick stuff. I'm sometimes right about where the problem was, and sometimes quite surprised. It's those latter cases that justify this strategy - it keeps me from barking up the wrong tree. (except once, a week or so ago. I was tracking down a bug that I believed to be in druntime. So I recompiled druntime in debug mode. At that point, it was 1am, so I went to bed. When I woke up the next day... I forgot it was still in debug mode. So I went to the site, and was annoyed to see it took almost 30 seconds to load one of the features. That's unacceptable. It was a new feature with some fairly complex code, so it didn't occur to me to check druntime. I did the profiling and found a few slow parts in dom.d. Fixed them up and got a 20x speedup. But, it was still taking several seconds. Then, I remembered about druntime! Recompiled it in the proper release mode, and it was back to the speed I'm supposed to get - single digit milliseconds. Yeah, it's still 20x faster than it was, but 40 ms isn't /too/ bad... Oh well though, while it was unnecessary, the profiling strategy did still give good returns for the effort put in!) I've had problems with database queries being slow, but they have always been either complex queries or poorly designed tables. I've never had a problem with reading or writing out sessions. Another profiling story with the db query, but I'll spare you this time. Then again, I only write sessions once when a use logs in, and reads are quick. So even if the system was slow, it wouldn't matter much. Fun fact: the fastest page load is no page load. Client side caching is built into http... but it seems to be rarely used. If you mix code and data, you're screwed - you can't write out an HTTP header after output has been generated! My cgi.d now includes more than just the header() function though. It keeps an updatable cache time, that you can set on each function, and is output as late as possible. That means you can set caching on the individual function level, making it easy to manage, and still get a good result for the page as a whole. Caching static content is obviously a plus. Caching dynamic content can be a plus too. I've gotten some nice usability speed boosts by adding the appropriate cache headers to ajax calls. Even expiring in just a few minutes in the future is nice for users. (Of course, the fastest javascript is also no javascript... but that's another story.)
 But what do you mean by "independently"?
Let me give an example. I briefly attended college with a "web app" that was just a barely functional front end to an old COBOL app on the backend. The entire site was dependent on that flow - it kept a lot of state server side. If you click add class in a new window, then go to view schedule in the current window... both windows will fail. The view schedule will error out because that's not a proper add class command. Add class window will fail because it errored out in the other window. The thing was a godawful mess to use. You have to do it linearly, in just one window, every time. Ugh. If it were better designed, each individual page would contain all the state it needed, so each tab works without affecting the other. This is an extreme example, and there's some times where a little bit of sharing is appropriate. But, even then, you should ask yourself is server side sessions are really the right thing to do.
 *snip*
 Ah, here we are.
Yeah, you didn't have to do a line by line breakdown for something I discussed in the following paragraph. Though, I will say handling things like adwords and webmail don't need sessions beside logging in and maybe cookies, and if you use them, your site is poorly designed. Database access vs a session cache is another thing you'd profile. I suspect you'd be surprised - database engine authors spend a lot of time making sure their engine does fast reads, and frequently used tables will be in a RAM cache.
 It *can* enforce, by refusing non-encrypted connection, or
 redirecting to https when access is done by http.
My point is it requires server setup too, like buying and installing a certificate. You can't *just* redirect and have to work.
 Not really - process should flush any dirty data to persistent
 storage and quit, so new copy may catch on.
Indeed - you're using some kind of database anyway, so the advantage of the long running process is diminished.
May 16 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:iqrj55$24d8$1 digitalmars.com...
 Alexander wrote:

 Database access vs a session cache is another thing you'd profile.
 I suspect you'd be surprised - database engine authors spend a lot
 of time making sure their engine does fast reads, and frequently
 used tables will be in a RAM cache.
Yea, that's really one of the main points of a DBMS: Efficient access to large amounts of data. Although I'd imagine accessing a DB for simple things could easily end up slower if the DB is on a different server. Big companies will often have setups like. Then again, if the network is all designed as set up well, and not congested, and the DB does have the data in RAM cache, then I'd imagine the lack of needing to do physical disk I/O could still make it faster.
 It *can* enforce, by refusing non-encrypted connection, or
 redirecting to https when access is done by http.
My point is it requires server setup too, like buying and installing a certificate. You can't *just* redirect and have to work.
That's not as bad as you may think, I've done that for my server recently. I *highly* recommend StartSSL. Most SSL/TLS certs are pretty expensive, but StartSSL has a free one: http://www.startssl.com/?app=1 The only real limitations are: - You have to renew it every 1 year. - Each cert is only good for one domain, and no subdomains (although the "www" subdomain is included for free, in addition to "no subdomain"). - The only validation it does is validation of the domain and contact email. There are, naturally, some hoops to jump through when setting it up (generating/installing a client certificate first so you can authenticate with their site). But their site walks you through everything step by step, and if you just follow the directions you can have it all done in minutes. Their system does require JS, and doesn't really handle using multiple tabs, but they don't do any annoying flashiness with the JS, and even my notoriously JS-hating self still finds it well worth it. I've been using it on my site for a little over a year and haven't had any problems. It's been great.
May 16 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Nick Sabalausky:
 Then again, if the network is all designed as set up well, and
 not congested, and the DB does have the data in RAM cache, then I'd
 imagine the lack of needing to do physical disk I/O could still
 make it faster.
Yeah, I work with two setups like that, but in my cases the db servers are on very fast local network links, so it wasn't a problem. It comes back to the same key of optimization though: profile it in real situations, since there's a lot of factors that are hard to guess by gut alone.
 That's not as bad as you may think, I've done that for my server recently.
Yeah, I've recently started using startssl too. They seem to be doing it the way it ought to be done!
May 16 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqm4ru$qj3$1 digitalmars.com...
 On 13.05.2011 17:19, Adam D. Ruppe wrote:

 It's *much* better, especially for rapid development. The compiler
 will tell me if my changes anywhere break things anywhere else,
 so I can modify with confidence.
Sure, there are many pros. And one significant drawback - it couldn't be easily embedded into HTML code. Either, you have to generate all your pages from inside of CGI script, or use templates - but the main advantage of PHP is that you can mix it with page text.
That's not an advantage at all. That was considered an advantage of PHP (and ASP) ages ago, but then web developers quickly discovered that was a horrible, horrible thing to do and caused nothing but terrible code. Even the PHP/ASP worlds have pretty much abandoned that, and for good reason.
May 14 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 14.05.2011 21:48, Nick Sabalausky wrote:

 That's not an advantage at all. That was considered an advantage of PHP (and 
 ASP) ages ago, but then web developers quickly discovered that was a 
 horrible, horrible thing to do and caused nothing but terrible code.
*All* developers? ;) Sorry, I've to disagree - still there are way too many projects where this is not considered "horrible" (just two quite popular examples - Drupal & Wordpress).
 Even the PHP/ASP worlds have pretty much abandoned that, and for good reason.
Many examples in documentation (both for PHP and ASP), including various tutorials, show how to mix the code and the data - this means "abandoned"? Perhaps, you could tell me this "good reason"? I see no good reasons, to be honest. /Alexander
May 14 2011
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
  *All* developers? ;) Sorry, I've to disagree - still there are way
 too many projects where this is not considered "horrible" (just two
 quite popular examples - Drupal & Wordpress).
with for work... (in the OT subthread where I talked about immutable $_POST, that was inspired by some awful code inside Wordpress!) The template system (see next) has lots of required boilerplate and ugliness too. Take a look at twentyten/header.php for some examples. a template system too - the themes folder. Sure, PHP is it's template language, but it does separate the main code from the template code. It fits under the category of disciplined php I touched upon in my document. I don't know drupal so I can't comment on that.
May 14 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 01:25, Adam Ruppe wrote:


work...
It works, and does it well enough. There are many projects which look horrible in the code, but the fact is - they work. But, perhaps, you may suggest an ideal blog engine? Where everything is done right?

 a template system too - the themes folder. Sure, PHP is it's template
 language, but it does separate the main code from the template code.
That's where I see the mixture of language and templates. XML templates look horrible - but this is just a question of taste :) In some of my projects, I want to have code on pages, so I can transform and manipulate the data - because sometimes business logic fits perfectly into pages, not the application, especially when you don't have source for application and want to change/extend something. If someone would ever make D to work exactly like PHP or ASP does (I mean - integration into templates) - then it would be perfect for me. Yes, may be "horrible" (to you or some others) - but I'll be more productive than with DOM-XML templates :) /Alexander
May 15 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
 XML templates look horrible - but this is just a question of taste
But Wordpress' code *is* an xml template, just with other crap mixed in. One of the downsides of me writing my document in notepad is adding code examples in a pain. I didn't want to manually write &lt;div&gt; over and over again, so I just sidestepped it. But, here's a template from my D demo: http://arsdnet.net/apidemo-document.html It's standard HTML, nothing more. The same stuff you'd write in an ugly PHP file, but without the ugly PHP. The main difference is I didn't have to repeat myself over and over. Didn't have to separate the header, the footer, and the content (though, I could have. Most my real sites actually do that.) I didn't have to write <div id="page-content"> <?php output_page_content(); ?> </div> And a corresponding function in the code. The id on the div is everything it needed to know. Another one: <table class="striped" id="our-data"> </table> That's all that's needed to be said in the template. The program uses the ID to fill in the data, and the class is caught in a generic post-processor to add class="odd" to every other row. (that is like unobstructive javascript for progressive enhancement, but done server side instead of on page load.) Such with PHP's Smarty templates would look like this: <table> {foreach from=$rows item=row} <tr class="{cycle values="odd,even"}"> <!-- output data here --> </tr> {/foreach} </table> Ugh. (and I forgot a closing tag there in my first draft! Would have broken the site. With the DOM, such things are rare since you write less xml (ironically), cleaner code, and if you mess up anyway, you get a clear message on where the missing tag is.) The D side, btw, looks like so: auto table = cast(Table) document.getElementById("our-data"); foreach(row; data) table.appendRow(row...); Much easier than the PHP equivalent too - it's all clear. And all properly closed and entity encoded with zero effort.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 17:36, Adam D. Ruppe wrote:

 But Wordpress' code *is* an xml template, just with other crap mixed in.
Not really "XML template". XML template, in my view, is something that is pure XML, without any code in it. In WordPress, those are mix of HTML and code, nothing more.
 One of the downsides of me writing my document in notepad is adding code
examples in a pain. I didn't want to manually write &lt;div&gt;
 over and over again, so I just sidestepped it.
Well, normally, code examples are not something which is displayed on (say) internet shop pages ;) I couldn't even remember when I had to do this last time, to be honest - so quoting is not a concern for me. Perhaps, you don't need it, but I do want to have an option to modify application logic on the fly, in the template or any other dynamic page, that's why I like mix of code and data - especially when the code is insignificant fraction of data.
 The D side, btw, looks like so:
 
 auto table = cast(Table) document.getElementById("our-data");
 foreach(row; data)
    table.appendRow(row...);
 Much easier than the PHP equivalent too - it's all clear. And all properly
closed and entity encoded with zero effort.
"all clear" to you - who is the author :) To me, this all is not so clear - as I don't know (=see) where exactly in the document all this happens. The whole reason to mix code with templates is to see where specific values are written, that's why to me code like: <div id="page-content"> <?php output_page_content(); ?> </div> is much more clear - whatever it is - PHP, ASP, D or something else. You may call it ugly, bad practice, incorrect, etc - that's, probably, is true for you - but not for everyone out there. People have different preferences :) Some even like to write HTTP servers in bash or postscript, and, though this is doable - it is not really practical to anyone who is used to something different - that's what I want to say. /Alexander
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander wrote:
  Perhaps, you don't need it, but I do want to have an option to
  modify application logic on the fly, in the template or any other
  dynamic page, that's why I like mix of code and data - especially
  when the code is insignificant fraction of data.
I think you'll feel differently once you see people abuse that option. It becomes hard to follow what's going on. Then, when the customer reports a bug or a change, you spend all night pounding your head over it instead of 5 minutes doing it, then goofing off arguing on newsgroups for the rest of the day :P
 all clear" to you - who is the author :) To me, this all is not
 so clear - as I don't know (=see) where exactly in the document
 all this happens.
You're also not used to it. (When I write this for newbies, I often put a comment in there: <!-- filled by program -->) It's an easy pattern though: an empty element with an ID is meant to be filled in, and the ID should be descriptive enough to make a good guess at what it's doing. (at least no worse than guessing a function's behavior based on it's name. Similarly, knowing what ID to use is the same as knowing what function to use.) I sometimes get concerned that the id's will get out of sync, or the new guy won't understand what's going on, but it hasn't been a problem in practice. After you see it used once, it's not a mystery anymore.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 19:36, Adam D. Ruppe wrote:

 I think you'll feel differently once you see people abuse that option. It
becomes hard to follow what's going on.
Sure I will feel differently, that's why I've said "if used correctly" - and I do use it correctly :)
 You're also not used to it. (When I write this for newbies, I often put a
comment in there: <!-- filled by program -->)
That kind of a comment made me crazy many times - because then I had to dig inside the program to find the place where it was filled :)
 It's an easy pattern though: an empty element with an ID is meant to be filled
in, and the ID should be descriptive enough
 to make a good guess at what it's doing.
If at some point I want to change output from table view to something else - then I've to change the application as well, as it generates series of tr/td elements, which I don't need anymore. To me, it is much easier to change it in place - i.e. where this is done actually. Bouncing from template to code is quite annoying, to be honest, especially when that code is not your own :)
 After you see it used once, it's not a mystery anymore.
It is not a mystery, just something that is blocking my productivity :) I just don't like it - and because of this I am less productive. From my point of view, it makes no sense to say "that is wrong" or "that is bad" - unless there is *objective* (and only) way to do something *right* - which is not the case in web development (and any software development in general). So, to some people (including myself) unless and until D may be embedded like PHP/ASP, it will be a show stopper. For some others - it will not, that's all. For this reason, I prefer to use D as a backend only (=performance critical), and frontends will be in PHP or ASP (=UI only). Though, currently I evaluate option to use D to host a server (HTTP) with dmdscript as server-side scripting language. What blocks me is the absence of good, robust and high-performance socket/file I/O framework for D2. /Alexander
May 15 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Alexander:
 That kind of a comment made me crazy many times - because then I
 had to dig inside the program to find the place where it was filled
Meh, is it any worse than digging into the program to figure out what a function referenced in the template does?
 If at some point I want to change output from table view to
 something else - then I've to change the application as well
Not necessarily - you could add format strings to the html, or have the output dependent on the tag name. The Javascript access to my code I pointed to earlier includes this: HTML, using a custom formatter provided by the Person object: http://arsdnet.net/cgi-bin/apidemo/get-people?startingId=0&format=html String, using a part custom, part automatic formatter: http://arsdnet.net/cgi-bin/apidemo/get-people?startingId=0&format=string Table, using an automatic formatter: http://arsdnet.net/cgi-bin/apidemo/get-people?startingId=0&format=table Json, using an automatic formatter: http://arsdnet.net/cgi-bin/apidemo/get-people?startingId=0&format=json The D function simply returned a Person[]. The formatting is flexible, automatic in a lot of cases, hookable by the object if needed. But, in a lot of cases, you have to change the model to change the data you're showing anyway... the view only has what's available to it. Even when mixed php code/data, you're going to either repeat yourself a lot, or be limited by what's available in existing functions or in the database. The semantics of the data won't change without touching app code, so the tags at this low level probably won't either. Changing their appearance is done by CSS. Take this table: http://arsdnet.net/cgi-bin/apidemo/get-people?startingId=0&format=table Want to show it as a list? Use CSS: table { display: block; border: none; padding-left: 2em; } thead { display: none; } tr { display: list-item; } th, td { display: inline; border: none; margin-left: 0.2em; } Boom, the table now looks like an unordered list. Semantically though, it's still tabular data, and the markup reflects that. See it live here: http://arsdnet.net/get-people.htm
 What blocks me is the absence of good, robust and
 high-performance socket/file I/O framework for D2.
When I wrote my http code, one of which is a kind of proxy/webapp build in one, so it does server and client work, I just used the appropriate C functions. Everything accessible from C is also accessible from D, so even if phobos isn't quite up to it, you can always do without. I agree it will be nice when phobos' offering improves though.
May 15 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
I wrote:
 When I wrote my http code,
I just spent a little time updating this. It's still built on my old netman.d, which uses Linux system calls so prolly linux only (it does select() and friends directly, should be easy enough to port to WinSock or std.socket but I wrote what I knew and left it at that). Removed some of the logic since the CGI class does it in a more structured way, and added support for HTTP 1.0 and better support for non-conforming clients. These steps aren't really necessary to work - today's browsers know to use \r\n and HTTP 1.1, but the ab program - apache benchmark - does not, and I wanted to see what happens when I attack it. Cache headers (if-modified, etc.) are not handled properly on the server, and cgi.d doesn't expose them at this time. This thing isn't meant to be used in production, unless it's in the back end, behind something more battle tested and standards conformant, like Apache. That said, ab's results weren't too bad if and only if the handler runs quickly. The reason for that is it is single-threaded. (the network manager class is based on a cooperative multitasking setup - each connection gets it's onDataReceived function called when new data comes in. It needs to look at it and return as soon as possible. Fine when it's all simple code, but with more complex websites it probably won't be.) While it's only a couple hundred lines long so I can't complain too much, this concurrency issue will have to be addressed before I can say it's really suitable for serious work. ... but, it is good enough to function as a notification server! Async notifications are fast, even if single threaded. Anyway while the implementation needs work, I am pretty happy with the api. Here's some code: import arsd.httpd; // the handler function is identical to one written with standard // CGI void handler(Cgi cgi) { cgi.write("Hello!"); cgi.write(to!string(cgi.get)); // show dynamic output cgi.close(); } // but instead of mixing in GenericMain or whatever, we call // serveHttp. void main() { // function pointer to handler, port to listen on serveHttp(&handler, 5000); } Nice and simple!
May 15 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-05-15 21:19, Adam D. Ruppe wrote:
 But, in a lot of cases, you have to change the model to change
 the data you're showing anyway... the view only has what's available
 to it.
Depending on what needs to be changed this is the job of the controller, to get the necessary data, for a specific view, out of the model. But, of course, if the model doesn't have the data in the first place that would be impossible. -- /Jacob Carlborg
May 16 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqp58d$3lh$1 digitalmars.com...
  From my point of view, it makes no sense to say "that is wrong" or "that 
 is bad" - unless there is *objective* (and only) way to do something 
 *right* - which is not the case in web development (and any software 
 development in general).
That's just plain rediculous. Software development isn't some damn hippie commune where "There are never any wrong answers, just different opinions! Tee hee hee :) :) :)". There *are* better ways and worse ways to do many things. Despite what everyone seems to have been brainwashed into believing these days, not everything is a matter of personal preference or opinion. Fuck, what's next? "Well, *for me* I like to have 2+2 equal 5, you can't say it's wrong, it's just my preference and my opinion." If some city architect decided to make the primary structural frame of a giant high-rise out of wood because "I like it, and it works well for me", that stupid screw-up would get fired on the spot, drummed out of the industry, and for good reason.
May 15 2011
parent Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 22:53, Nick Sabalausky wrote:

 That's just plain rediculous. Software development isn't some damn hippie 
 commune where "There are never any wrong answers, just different opinions! 
It is. There are *many* ways to do the same thing in software, using different languages, technologies and patterns.
 There *are* better ways and worse ways to do many things.
OK, turning 2 into 1 and vice versa, assuming X always holds 2 or 1: 1. 3 - X 2. X ^ 3 Which one is better? Expand this to couple dozens of languages - which is better, which is worse?
 Despite what everyone seems to have been brainwashed into believing 
 these days, not everything is a matter of personal preference or opinion. 
Sure, not everything. But software development - is. There are, sure, better and worse ways to do things, but still, there are *many* of them - on both sides.
 If some city architect  decided to make the primary structural frame of a
giant high-rise out of 
 wood because "I like it, and it works well for me", that stupid screw-up 
would get fired on the spot,
 drummed out of the industry, and for good reason.
Nope. There are *many* ways for architects to build. Many materials, and as long as one or another does whatever is expected from it - it works. This is not only about "works for me" - this is about - "works as ordered by the customer", "works as it should" and "works according to specifications". And surely, there are *many* ways to achieve *same* results - in many different areas, including architecture. /Alexander
May 15 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-05-15 20:11, Alexander wrote:
 On 15.05.2011 19:36, Adam D. Ruppe wrote:

 I think you'll feel differently once you see people abuse that option. It
becomes hard to follow what's going on.
Sure I will feel differently, that's why I've said "if used correctly" - and I do use it correctly :)
 You're also not used to it. (When I write this for newbies, I often put a
comment in there:<!-- filled by program -->)
That kind of a comment made me crazy many times - because then I had to dig inside the program to find the place where it was filled :)
 It's an easy pattern though: an empty element with an ID is meant to be filled
in, and the ID should be descriptive enough
 to make a good guess at what it's doing.
If at some point I want to change output from table view to something else - then I've to change the application as well, as it generates series of tr/td elements, which I don't need anymore. To me, it is much easier to change it in place - i.e. where this is done actually. Bouncing from template to code is quite annoying, to be honest, especially when that code is not your own :)
 After you see it used once, it's not a mystery anymore.
It is not a mystery, just something that is blocking my productivity :) I just don't like it - and because of this I am less productive. From my point of view, it makes no sense to say "that is wrong" or "that is bad" - unless there is *objective* (and only) way to do something *right* - which is not the case in web development (and any software development in general). So, to some people (including myself) unless and until D may be embedded like PHP/ASP, it will be a show stopper. For some others - it will not, that's all. For this reason, I prefer to use D as a backend only (=performance critical), and frontends will be in PHP or ASP (=UI only). Though, currently I evaluate option to use D to host a server (HTTP) with dmdscript as server-side scripting language. What blocks me is the absence of good, robust and high-performance socket/file I/O framework for D2. /Alexander
BTW, someone modified MiniD to support the <% %> syntax to embed it in html. -- /Jacob Carlborg
May 16 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqobn4$1h7v$1 digitalmars.com...
 On 15.05.2011 01:25, Adam Ruppe wrote:


 with for work...
It works, and does it well enough. There are many projects which look horrible in the code, but the fact is - they work.
It *barely* works. And I *did* stop using it specifically because it worked so poorly.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 22:56, Nick Sabalausky wrote:

 It *barely* works. And I *did* stop using it specifically because it worked 
 so poorly.
Don't get it too personally, but probably, you didn't read the manual? ;) It works perfectly, even for those who are *not* familiar with software of web development. /Alexander
May 15 2011
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 15/05/2011 22:44, Alexander wrote:
 On 15.05.2011 22:56, Nick Sabalausky wrote:
 It *barely* works. And I *did* stop using it specifically because it worked
 so poorly.
+1
    Don't get it too personally, but probably, you didn't read the manual? ;)

    It works perfectly, even for those who are *not* familiar with software of
web development.

 /Alexander
It most definitely does not work perfectly. You highlight those that are not familiar with web development? They're the ones that use it. Visual Studio defaults to not using it now, there's a reason for that. I don't know about PHP IDEs. -- Robert http://octarineparrot.com/
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 16.05.2011 01:25, Robert Clipsham wrote:

 It most definitely does not work perfectly. You highlight those that are not
familiar with web development? They're the ones that use it.
 
 Visual Studio defaults to not using it now, there's a reason for that. I don't
know about PHP IDEs.
I am sorry, but do we talk about the same thing? How is WordPress related to Visual Studio, especially how could it "use it"? /Alexander
May 16 2011
parent Robert Clipsham <robert octarineparrot.com> writes:
On 16/05/2011 09:54, Alexander wrote:
 On 16.05.2011 01:25, Robert Clipsham wrote:

 It most definitely does not work perfectly. You highlight those that are not
familiar with web development? They're the ones that use it.

 Visual Studio defaults to not using it now, there's a reason for that. I don't
know about PHP IDEs.
I am sorry, but do we talk about the same thing? How is WordPress related to Visual Studio, especially how could it "use it"? /Alexander
My bad, I was rather tired when I posted this, I thought I was replying to something else. Sorry! -- Robert http://octarineparrot.com/
May 16 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqmrh6$22b0$1 digitalmars.com...
 On 14.05.2011 21:48, Nick Sabalausky wrote:

 That's not an advantage at all. That was considered an advantage of PHP 
 (and
 ASP) ages ago, but then web developers quickly discovered that was a
 horrible, horrible thing to do and caused nothing but terrible code.
*All* developers? ;) Sorry, I've to disagree - still there are way too many projects where this is not considered "horrible"
There's always shitty programmers out there. *Especially* in web development.
 (just two quite popular examples - Drupal & Wordpress).
Not familiar with drupal. Wordpress is pure shit. And no, popularity does *not* equate to quality.
 Even the PHP/ASP worlds have pretty much abandoned that, and for good 
 reason.
Many examples in documentation (both for PHP and ASP), including various tutorials, show how to mix the code and the data - this means "abandoned"?
You're being extremely nitpicky.
  Perhaps, you could tell me this "good reason"? I see no good reasons, to 
 be honest.
Do it professionally for a few years and you'll see the reasons.
May 14 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:iqnl10$au2$1 digitalmars.com...
 "Alexander" <aldem+dmars nk7.net> wrote in message 
 news:iqmrh6$22b0$1 digitalmars.com...
 On 14.05.2011 21:48, Nick Sabalausky wrote:

 That's not an advantage at all. That was considered an advantage of PHP 
 (and
 ASP) ages ago, but then web developers quickly discovered that was a
 horrible, horrible thing to do and caused nothing but terrible code.
*All* developers? ;) Sorry, I've to disagree - still there are way too many projects where this is not considered "horrible"
There's always shitty programmers out there. *Especially* in web development.
As an example, I once worked at a place where the code was all VB6, it was filled with meaningless variable names like "stbbb" and "aaa", and they frequently used the following idiom: If {condition} Then {do stuff} Goto label End If {do stuff} label: All of that *was considered acceptable practice*. But the fact they found it acceptable obviously doesn't change the fact that those are horrible practices: it just meant they were a bunch of complete fucking amateur morons. And such people are *all over* web development. Full time, with a salary. It's pathetic, but very, very true. So no, of course not "all" developers consider classic-style-PHP code/html-mixing to be horrible, but the ones who actually have at least somewhat of a clue what the hell they're doing certainly do.
May 14 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 06:42, Nick Sabalausky wrote:

 All of that *was considered acceptable practice*. But the fact they found it 
 acceptable obviously doesn't change the fact that those are horrible 
 practices: it just meant they were a bunch of complete fucking amateur 
 morons.
Until and unless we have clear definition of "good practice", which is acceptable and practiced my majority, the definition of "good" and "bad" is purely point of view and extremely subjective. Sorry, but the only thing I wanted to say - is that in some cases D is not good for dynamic web (don't want to repeat myself - why). You don't think so? Good, follow whatever you believe is good - no questions, no problems. Just recognize that there are many people and many opinions and practices, which are good or bad for any particular application - that's all. Really, I don't want to start a flame - what is good or bad. Just expressing my opinion :) /Alexander
May 15 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqocgq$1iko$1 digitalmars.com...
 On 15.05.2011 06:42, Nick Sabalausky wrote:

 All of that *was considered acceptable practice*. But the fact they found 
 it
 acceptable obviously doesn't change the fact that those are horrible
 practices: it just meant they were a bunch of complete fucking amateur
 morons.
Until and unless we have clear definition of "good practice", which is acceptable and practiced my majority, the definition of "good" and "bad" is purely point of view and extremely subjective.
And like I said at the beginning, the old-style-PHP/ASP of mixing code and HTML is one of the things that *HAS* become widely accepted as bad practice. Just because there are some amateurs and incompetent "professionals" around that still don't know any better doesn't change that fact.
  You don't think so? Good, follow whatever you believe is good - no 
 questions, no problems. Just recognize that there are many people and many 
 opinions and practices, which are good or bad for any particular 
 application - that's all.
Ugh, I never could stand that hippie rhetoric. Despite what society's been brainwashed into believing, there *ARE* opinions out there that are just plain moronic, and yes, *wrong*.
May 15 2011
parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 23:05, Nick Sabalausky wrote:

 And like I said at the beginning, the old-style-PHP/ASP of mixing code and 
 HTML is one of the things that *HAS* become widely accepted as bad practice. 
Could you please back your claims with something? I know already that you are the kind of person who knows better, and you are used to speak for everyone, but that's just words.
 Just because there are some amateurs and incompetent "professionals" around 
 that still don't know any better doesn't change that fact.
And you are professional? Show me something that is professional, so I can learn.
 Ugh, I never could stand that hippie rhetoric. Despite what society's been 
 brainwashed into believing, there *ARE* opinions out there that are just 
 plain moronic, and yes, *wrong*.
And yours is always *right*? ;) /Alexander
May 15 2011
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 15/05/2011 22:46, Alexander wrote:
 On 15.05.2011 23:05, Nick Sabalausky wrote:

 And like I said at the beginning, the old-style-PHP/ASP of mixing
 code and HTML is one of the things that *HAS* become widely
 accepted as bad practice.
Could you please back your claims with something? I know already that you are the kind of person who knows better, and you are used to speak for everyone, but that's just words.
I can't be bothered collecting lots of references, but having done web development both professionally (not as much as Nick) and non-professionally, I can tell you that it *is* widely accepted as bad practice. I've found the people that don't agree with that are either (reasonably) new to web development, or don't really know what they're doing.
 Just because there are some amateurs and incompetent
 "professionals" around that still don't know any better doesn't
 change that fact.
And you are professional? Show me something that is professional, so I can learn.
 Ugh, I never could stand that hippie rhetoric. Despite what
 society's been brainwashed into believing, there *ARE* opinions out
 there that are just plain moronic, and yes, *wrong*.
And yours is always *right*? ;)
Meet the seasoned web developer - 99.9% of other web developers are idiots who can't code, and anyone who does it differently to you is wrong. After a certain amount of time working with the web, and several code bases that started as quick hacks to get the job done but evolved into entire websites with a good few users, you realize that most of the code out there is terrible. It gets the job done, sure, but it takes a lot of effort to debug or add new features. Anything you add to the code base just makes it harder to maintain, even if you start writing things properly. Want to re-factor something? Chances are you can't do it without breaking something. If you're curious, add: error_reporting(-1); To the start of most PHP applications, and see the large number of notices/warnings/errors which scroll past in your error log - over time the PHP developers (not developers that use PHP) have realized how many things can go wrong (register_globals, magic_quotes, safe_mode, etc), and added more warnings, notices and errors which aren't shown by default. I've encountered a good few developers which have said I shouldn't have enabled it and it's not their problem when working with their code. Note that things like wordpress use error_reporting() elsewhere, so adding error_reporting(-1); won't make any difference as it will be overridden. Of course, I'm not saying Nick is always right (I happen to disagree with him on a few things, just mention javascript to him to see what I mean :D), but you now have 3 developers with varying experience with the web telling you it's not the right thing to do. Sure, it's fantastic for quick sites, nice and fast to put something together... But when it evolves into a something bigger it will be a nightmare. Using a decent framework is just as fast, and it's easy to maintain later on. As for using D for web development... I'd use it even without a web framework, purely for the maintainability/error reporting issues mentioned earlier on. There are no frameworks available that I'm aware of other than Adam's currently (which I believe he's using professionally, so it has to be reasonably good), but something is better than nothing. I'm also working on my own, progress is slow though due to time constraints. Give it a few months and it might be workable.
 /Alexander
Seems I managed quite a rant there. Oops :D -- Robert http://octarineparrot.com/
May 15 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
Robert Clipsham:
 which I believe he's using
 professionally, so it has to be reasonably good)
Indeed, cgi.d, mysql.d, and dom.d have both been used on a few of my client's live sites for about a year now. If they have serious bugs, I've subconsciously learned to avoid them, since there's been little problems with them. sqlite.d and postgres.d seem to be ok, but haven't gotten as heavy use as mysql. The newer web.d, that I've been linking to as the apidemo, is used for some in development apps, but nothing that's launched yet. (Everyone is very excited about these in-dev apps though, it's been excellent during internal testing and I've made excellent time developing new features with it.) There's a number of helper modules too that work well, but are more tied to the application itself, so I haven't released them. (If there's potentially anything proprietary in a file at all, I hold the whole thing back unless I can find the time to carefully comb through it.) The two most likely to go public before too long are: email.d for talking to sendmail, Gmail relays, and recently added, Amazon SES. Also minimal includes MIME attachment support and a html to text converter for automatically making multipart messages. (they write html emails but I loathe them.) oauth.d for interacting with Facebook's apis (oauth 2) and Twitter, LinkedIn, and (buggy) AWeber (oauth 1). As of last night, it also has a minimal oauth 1 server implementation. Needs lots of testing. It's a pretty wide collection of stuff, with the base reasonably well tested. Most of it is nothing fancy though.
May 15 2011
prev sibling parent reply Alexander <aldem+dmars nk7.net> writes:
On 16.05.2011 01:21, Robert Clipsham wrote:

 I can't be bothered collecting lots of references, but having done web
development both professionally (not as much as Nick) and non-professionally, I
can tell you that it *is* widely accepted as bad practice.
Accepted as bad practice by whom? Looks like there is very small fraction of "real" web developers, who is deciding what is "bad practice", as almost anything which is public widely using it. Times change, and something was considered as "good practice" may change to "bad practice" in few years, and vice versa - I've seen that enough in last 20 years.
 ...but you now have 3 developers with varying experience with the web telling
you it's not the right thing to do.
I am sorry, but I didn't see any works of those web developers (I mean - the code), so I couldn't make my mind - what is *good* practice, and why it is better than anything else (again - *if done properly*). Good practice, from my point of view, is something that: - Easy to understand; - Easy to maintain; - Easy to extend; - Does its job well (according to specifications); - Has good performance; - Doesn't have any holes. So, it doesn't matter, how exactly specific solution is implemented, as long as all of those point are met. I can mix code with data or use DOM templates - as long as I fulfill the above stated requirements, it really doesn't matter. It is like my recent question about class member declaration order - I find it harder to understand the code, when members are not declared before use, though, others (on this list) tend to disagree with me. Who is right here? /Alexander
May 16 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqqq9p$ka6$1 digitalmars.com...
 On 16.05.2011 01:21, Robert Clipsham wrote:

 I can't be bothered collecting lots of references, but having done web 
 development both professionally (not as much as Nick) and 
 non-professionally, I can tell you that it *is* widely accepted as bad 
 practice.
Accepted as bad practice by whom? Looks like there is very small fraction of "real" web developers, who is deciding what is "bad practice", as almost anything which is public widely using it.
The vast majority of web developers *are* very, very, poor coders. Being correct and being in the majority have absolutely *nothing* to do with each other.
  Times change, and something was considered as "good practice" may change 
 to "bad practice" in few years, and vice versa - I've seen that enough in 
 last 20 years.
That's an enormous oversimplification.
 ...but you now have 3 developers with varying experience with the web 
 telling you it's not the right thing to do.
I am sorry, but I didn't see any works of those web developers (I mean - the code), so I couldn't make my mind - what is *good* practice, and why it is better than anything else (again - *if done properly*). Good practice, from my point of view, is something that: - Easy to understand; - Easy to maintain; - Easy to extend; - Does its job well (according to specifications); - Has good performance; - Doesn't have any holes. So, it doesn't matter, how exactly specific solution is implemented, as long as all of those point are met. I can mix code with data or use DOM templates - as long as I fulfill the above stated requirements, it really doesn't matter. It is like my recent question about class member declaration order - I find it harder to understand the code, when members are not declared before use, though, others (on this list) tend to disagree with me. Who is right here?
When you're not doing trivial stuff, the traditional mix-code-and-html approach fails miserably at: - Easy to maintain; - Easy to extend; - Doesn't have any holes. And it also causes this to become a bigger and bigger problem as a project progresses: - Easy to understand; All of that, in turn, makes this MUCH, MUCH harder than it would otherwise be: - Does its job well (according to specifications);
May 16 2011
parent Alexander <aldem+dmars nk7.net> writes:
On 16.05.2011 12:23, Nick Sabalausky wrote:

 The vast majority of web developers *are* very, very, poor coders. Being 
 correct and being in the majority have absolutely *nothing* to do with each 
 other.
Sorry, but I still don't get it - who is defining what is correct and what is not? And why?
 When you're not doing trivial stuff, the traditional mix-code-and-html 
 approach fails miserably at:
 
 - Easy to maintain;
 - Easy to extend;
 - Doesn't have any holes.
Why it fails here? Why it doesn't fail for me? Or some other people? Sure there are always poor coders who could fail anything, but not everyone.
 And it also causes this to become a bigger and bigger problem as a project 
 progresses:
 
 - Easy to understand;
As long as you follow some simple rules when coding, nothing bad happens. On the other hand, there always people who don't understand your code, and you - theirs. What is difficult for you, may be piece of cake for someone else, and vice versa - it is all bound to how your barin works :) Some people easily and in few minutes do sophisticated stuff in languages like BrainFuck, while for me that will be exactly what name of this language means. Exactly the same thing applies to web development (and any development) - is it easy to understand or not, depends on who is trying to understand. And no, you simply cannot make something very complex so easy that anyone will understand it like you (the author) do.
 All of that, in turn, makes this MUCH, MUCH harder than it would otherwise 
 be:
 
 - Does its job well (according to specifications);
I know personally at least one project, which fail miserably in many, many points - but does it's job *very* well for more than 10 years. How is this linked then? Or, look at djb code (qmail & co) - the code itself is terrible, still, one of the most used - and less buggy that many "well designed" and "good practiced" projects. The only example of good code and good practice that I ever knew is cryptlib, though this is not exactly related to web development... /Alexander
May 16 2011
prev sibling parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 06:28, Nick Sabalausky wrote:

 There's always shitty programmers out there. *Especially* in web development.
Looks like most of them are, right? :)
 Not familiar with drupal. Wordpress is pure shit. And no, popularity does
*not* equate to quality.
From end user point of view, "quality" is something that defines how good application is performing, not how it is written. IMHO.
  Perhaps, you could tell me this "good reason"? I see no good reasons, to be
honest.
Do it professionally for a few years and you'll see the reasons.
WordPress developers (not all, of course, but some) do it professionally for many years, still, whatever they do, you call it "pure shit", and they don't see the reasons you see. That's why I asked about "good reason" - a guideline to follow, which is rational for anyone. /Alexander
May 15 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqoc6r$1hqu$1 digitalmars.com...
 On 15.05.2011 06:28, Nick Sabalausky wrote:

 There's always shitty programmers out there. *Especially* in web 
 development.
Looks like most of them are, right? :)
Unfortunately, yes.
 Not familiar with drupal. Wordpress is pure shit. And no, popularity does 
 *not* equate to quality.
From end user point of view, "quality" is something that defines how good application is performing, not how it is written. IMHO.
I've *been* a WordPress end user. It performed like shit. I got rid of it. I don't doubt there are many amateurs out there who could look straight at a total POS and not see the obvious problems. Just look at all the Apple fans.
  Perhaps, you could tell me this "good reason"? I see no good reasons, 
 to be honest.
Do it professionally for a few years and you'll see the reasons.
WordPress developers (not all, of course, but some) do it professionally for many years, still, whatever they do, you call it "pure shit", and they don't see the reasons you see.
Like I described in another post, I've *worked with* people who did web development professionally who still undeniably had nearly zero real competence. So you can't tell me just because they do it professionally indicates they actually have a clue what they're doing.
  That's why I asked about "good reason" - a guideline to follow, which is 
 rational for anyone.
Nothing is "rational for anyone" because most people are irrational imbeciles.
May 15 2011
next sibling parent reply Alexander <aldem+dmars nk7.net> writes:
On 15.05.2011 23:13, Nick Sabalausky wrote:

 I've *been* a WordPress end user. It performed like shit. I got rid of it.
There are many people who dislike Windows too - for the same reasons. But now, I want to know - which universe you are from? I never had any problems with WordPress nor Windows, despite the fact that forums are full of screams. Perhaps, you could tell me, what exactly doesn't work, so majority of users didn't notice and still use it? ;)
 I don't doubt there are many amateurs out there who could look straight at a 
 total POS and not see the obvious problems. Just look at all the Apple fans.
Sure, Apple has his share of problems. But they are rich and popular. Do you, with your "perfect solutions"? ;)
 Nothing is "rational for anyone" because most people are irrational imbeciles.
Thank you, Nick. Now I know who I am :) /Alexander
May 15 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqpi2b$pc7$1 digitalmars.com...
  Sure, Apple has his share of problems. But they are rich and popular. Do 
 you, with your "perfect solutions"? ;)
Sorry, I forgot that what's popular is always right and what's right is always popular.
May 15 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Alexander" <aldem+dmars nk7.net> wrote in message 
news:iqpi2b$pc7$1 digitalmars.com...
 Nothing is "rational for anyone" because most people are irrational 
 imbeciles.
Thank you, Nick. Now I know who I am :)
FWIW, I didn't intend anything I've said as anything personal against you. It probably did came across that way though. Wasn't my intent.
May 15 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-05-15 23:13, Nick Sabalausky wrote:
 Like I described in another post, I've *worked with* people who did web
 development professionally who still undeniably had nearly zero real
 competence. So you can't tell me just because they do it professionally
 indicates they actually have a clue what they're doing.
That seems to especially true with web development. -- /Jacob Carlborg
May 16 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-13 17:19, Adam D. Ruppe wrote:
 Jacob Carlborg wrote:
 How is it working out with a static type system, compared to a
 dynamic, for web development?
It's *much* better, especially for rapid development. The compiler will tell me if my changes anywhere break things anywhere else, so I can modify with confidence. I can't tell you how many times I've made a minor mistake in PHP, Ruby, or Visual Basic and had it slip through to production because the code path was obscure enough to evade testing.
That's what I really miss when doing web development in a language with a dynamic type system. It's hard to do any refactoring, always the possibility to break some code you had no idea would be affected.
 Sometimes, something similar does happen in D - to!int("") throws -
 but, the compiler catches the majority of incompatible changes
 instantly.

 If I had int addUser() and change it to User addUser(), I don't
 have to hunt every instance down myself. Just hit compile and
 the compiler tells me where the change causes problems. (Rarer than
 you might think - thanks to auto, a lot of the program is already
 duck typed in a way. The actual return value name is rarely used.)


 It also helps documentation to have good types. I often see stuff
 like this in dynamic language docs:

 function doSomething(options);

 What does it return? What options are available? Maybe the text
 will tell us that options is an associative array. UGH, I hate
 that! Now, there's even less knowing what's going on.
Actually that's one thing I really like with Ruby and Rails, that you can put different types of values in arrays and hashes. But I can agree, sometimes it's hard to know what options are available.
 D's documentation is a lot more helpful, and easier to keep up to
 date.

 string doSomething(Options options); // not much better yet....

 struct Options;
 int speed;
 bool strictMode;
 bool caseSensitive;


 Ahhh, now I know!
But that way you would need to declare different types of Options structs all over the place?
 Another thing that the static types enable that I don't think is
 possible with dynamic functions is the automatic forms you see
 on my link.

 http://arsdnet.net/cgi-bin/apidemo/get-a-box

 I didn't write any html for that. The library made it for me.

 In the source, you can see it's prototype:
 http://arsdnet.net/apidemo.d
 	Element getABox(Color color);


 The reflection was able to say "it needs a Color, and there's only
 a handful of valid Colors - enum Color - so I can automatically
 create a<select>  box for this."

 Dynamic types for return values can still do most the stuff my
 api generator does. Whether it's a static function/template toHtml
 or a dynamic property doesn't matter much.

 But the parameters... I don't think it can be done without the
 static types there.

 (Another nice thing is the library checks the type too. Coming
 off the request parameters, you have strings; dynamic types. But
 going into the function, it knows it must be a Color, so it
 checks. If not, an exception is thrown.

 By the time you're inside the function, you can be guaranteed that
 Color color is indeed a Color. Thus, to!string() to insert it into
 the html attribute that I did here is perfectly safe. It's a
 whitelist based filter, all done automatically.)



 There are a few cases where dynamic types are helpful or needed.
 D lets us opt in to them with only a minimal amount of fuss.

 The places where I use it are:

 1) Data from the user. Form variables are of type string coming
 into the program. Once decoded, you have string[][string]. Your
 program probably wants something else.

 The to!() template in Phobos makes this pretty easy, or if you
 want default value and get/post combined, my cgi class has a request
 template:

 int a = cgi.request!int("a");

 That's similar to this in PHP:

 $a = 0;
 if(isset($_POST['a']))
    $a = (int) $_POST['a'];
 else
 if(isset($_GET['a']))
    $a = (int) $_GET['a'];


 PHP is so outrageously verbose. And the PHP is buggy compared to
 the D... if you do cgi.request!int("a", 10) and the user does a=txt,
 the PHP result is wrong. It's not quite fair to compare a function
 to a code collection though. A php function could do it right too.
I think there are other languages available that is far better than PHP that you could compare with instead. Ruby on Rails: a = params[:a].to_i Depending on what you need this might not be the best way to write it. If :a doesn't exist in "params" it would return "nil" and "nil.to_i" would give you 0. If you use the Rails methods it will to the right thing most of the times without you need to worry about it. For example: Post.find(params[:a]) This will try to find a Post with the given id and automatically converted the given value to an integer. If it fails to convert the value to an integer it will return 0 (this is not the best solution and I don't like it). When it can't find a Post with the given value (you most likely won't have a an id in the database with the value 0) it will through an exception.
 Annnnyway, I'm digressing. Hell, I'm going on about weak types
 instead of dynamic types! Even in Ruby, you'd have to do a to_i
 since the url value simply is a string.



 Back to dynamic types. The three other places where you see them
 are databases and interfacing with external services.

 2) Databases

 With databases, you probably expect a certain type anyway. If the
 column is typed as INTEGER, you probably don't want 'lol' in there.
 But, the database takes care of that for you.


 In my libs, I just use strings.

 auto line = mysql.query("SELECT id FROM users WHERE id = 10").front;

 res[0] == "10"


 Conversions are now done the same as URL parameters:

 int id = to!int(res[0]);


 Oftentimes, I don't really care about it though; if I'm outputting
 it to html, I'll just say:

 table.appendRow(res["id"], res["name"])

 and the like anyway. You want a string there, so it just works.
 (appendRow is in fact a variadic template so it'd just work
 regardless, but you get the idea anyway).
I've been thinking for a while to try and create something similar as Rails' ActiveRecrod for D but every time I tried to do it turns out to work quite badly with a static type system. Either you would need to specify the columns and the types in the model class (which I would like to avoid) or you would have to use Variants all over the places. And if you use Variants all over the place then I don't so much reason in using a language with a static type system compared to a dynamic type system.
 Thanks to static checks though, if I were to later change my mind
 and wanted ints, or made the database return Variants or whatever,
 no problem - the compiler will point out trouble spots to me.


 Inserting data is the same:

 mysql.query("INSERT INTO users (id) VALUES (?)", 10); // works
 mysql.query("INSERT INTO users (id) VALUES (?)", cgi.post["id"]); // works too


 Or using the data object class:

 auto obj = new DataObject(mysql, "users");

 obj.id = 10; // works
 obj.id = "10"; // works just as well

 obj.commitChanges();

 (The DataObject can read too, offering database fields as obj.id
 style properties. They always return string, just like plain query,
 but are also read/write.)


 DataObject can also be specialized automatically to use static
 types if you like.

 db.sql:
 create table users(id integer primary key, name varchar(30));

 file.d:

 // parse out that create table to map the names and types automatically
 alias DataObjectFromSqlCreateTable!(import("db.sql"), "users") User;

 User a;

 a.id = "12"; // type mismatch, fails to compile
 a.name = "hello"; // works
 a.nmae = "sad" // typo caught at compile time

 a.commitChanges(); // otherwise it is still based on DataObject



 In short, I have the best of both worlds, with the only extra effort
 being writing to!() here and there and that one line to import the
 sql definition.


 3) HTML

 I *want* strict typing when working with html in almost all cases.
 It helps catch encoding bugs.

 The one place where I want dynamics - fetching an element off
 the html template - I have it, this time provided through classes.

 auto table = cast(Table) document.getElementById("data-table");
 assert(table !is null); // fails if it isn't a<table>  tag

 // use the table class's special functions


 Forms, Links, and other types of nodes are handled similarly. The
 Element base class though does most the simple operations. Being
 plain old inheritance, the virtual functions act dynamically
 enough.

 Of course, if the HTML changes, that assert/enforce will trigger
 at run time. We're still ahead of dynamic languages though: the
 compiler will tell me what breaks if I remove the cast, with one
 exception: I use an opDispatch there for attributes. That will
 break some functions.

 Table t = ...;

 t.caption = "Hello!"; // changes the<caption>  tag child

 Element t = ...;

 t.caption = "Hello!"; // sets a caption="" attribute


 But meh, in this case, I like the flexibility of accessing
 attributes like that. The compiler still catches more than it
 doesn't - we're still ahead of the mistakes possible in dynamic
 languages while keeping the convenience.


 4) External services


 This is where dynamic types are the most useful. Accessing Facebook,
 Twitter, etc., returns xml or json with types that change based
 on a lot of things. Is the user logged in? What url is it?

 In this case, it's like the database, but the types tend to be more
 complex. Simple string cowboying won't cut it.

 Thankfully, D's Variant is up to the task.


 Variant userRet = fbGraph(token, "/me");

 // we know /me returns a json object from the docs, so fetch it:

 auto user = userRet.get(Variant[string]);

 auto name = user["name"].get!string;

 // name is a string == "Adam D. Ruppe"


 Not terribly hard. Robert Jacques IIRC has written an improved
 std.json patch to make this work almost just like Javascript:

 auto user = fbGraph(token, "/me");

 user.name.get!string; // same as above


 So D's definitely up to the job. The only difference is that final
 use of get!string. I believe Phobos' to! works as well.
As I said above, I don't see the big advantage if I have to use Variants all over the place .
 In the end, there's nothing web related in my experience that a
 dynamic language can do that D can't do almost or just as well,
 and plenty that D and it's static types can do that dynamic types
 can't do, or require piles of painful tests and manually written
 code or documentation to do.


 D kicks the Web's ass. (And my web related libraries go even further
 than seen here. My custom DOM offers a lot of things that are way
 cool, enabling new CSS stuff, filling forms easily, in about 1/10
 the code of doing it similarly in PHP, and without mucking up the
 HTML. The web api/site generator makes D accessible through urls,
 forms, javascript - view the source here for a glimpse of that
 lib:
 http://arsdnet.net/cgi-bin/apidemo/javascript

 20 kb of javascript, including the auto generated API bindings!

 And more stuff is packed in there too. Best of all: D, through
 CGI, consistently does well or better than mod_php in my speed
 benchmarks. I've barely tried to optimize too; there's a lot of
 untapped potential.


 If your host doesn't suck, dive into D on the web. You won't want
 to go back.)
I don't know what your experiences are but since you mention PHP a lot I can agree with you, PHP sucks. Compared to PHP you can do a lot better, also with a dynamically typed language. Actually all the "native" languages in web development (HTML, CSS, JavaScript) are quite horrible. I don't know if it's just me but I try to hide those native languages as much as possible. I'm currently now uses Ruby on Rails with the following languages: * Ruby as the server side script (obviously) * HAML, generates HTML - http://haml-lang.com/ * SASS, generates CSS - http://sass-lang.com/ (I'm using the sass syntax and not the scss syntax) * CoffeeScript, generates JavaScript - http://jashkenas.github.com/coffee-script/ Every language is compiled to its native format automatically when needed and cached in production. I just tried Rails 3.1 beta yesterday and now SASS and CoffeeScript are default. I think these languages make web development a less of a pain, but in the end they all compile to their native languages and there is no way to get away from that. -- /Jacob Carlborg
May 15 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Jacob Carlborg wrote:
 But that way you would need to declare different types of Options
 structs all over the place?
Sometimes, but most functions are fine with regular argument lists, to me, using enums for options where appropriate.
 I think there are other languages available that is far better than
 PHP that you could compare with instead. Ruby on Rails:
Come to think to fit, PHP's $_REQUEST() would have worked here too and shaved off a couple lines. Anyway, I've used Ruby before, but never Rails. The to_i and to_s things are familiar.. me forgetting to write them caused many problems in that project. I hate dynamic languages so much. That Ruby project is what put the nail in the coffin. I want to get an idea of how Rails works though, so see how well my approaches stack up. But, aside from discussions like this one, I haven't had a chance to get into it.
 This will try to find a Post with the given id and automatically
 converted the given value to an integer.
This is similar to how my database libs work. It actually lets the database do the conversion though.
 I've been thinking for a while to try and create something
 similar as Rails' ActiveRecrod for D but every time I tried to do
 it turns out to work quite badly with a static type system.
Have you seen Piotr Szturmaj's Postgres code? http://www.digitalmars.com/d/archives/digitalmars/D/learn/D2_postgresql_interface_-_Phobos2_23693.html#N23695 (there's more posts than that on it too if you search) It might give you some ideas. I went the other way; I don't mind writing SQL. (I always find automatic mappings the other way to be inefficient and lacking anyway.)
 As I said above, I don't see the big advantage if I have to use
 Variants all over the place .
The thing is it's not *all* over the place. There's a small area where you use them, and you get the static type benefits everywhere else. Even with the variant areas, the static type system helps a little bit. At least misspelled variable names are caught ahead of time by the compiler.
 HAML, generates HTML - http://haml-lang.com/
Syntax and indenting aside, concepturally, that's similar to how my DOM based code works. auto profile = holder.addChild("div").className("profile"); auto left = profile.addChild("div").className("left column"); left.addChild("div", print_date).id("date"); left.addChild("div", current_user.address).id("address"); One big difference, semantically, is my code always escapes HTML by default. Looks like haml uses &= for escaping, while = does not.... so their homepage example is both incorrect and open to XSS attacks! (I offer two ways to write HTML: some functions take arguments of type Html, like Table.appendRow: table.appendRow("&nbsp;", Html("&nbsp;")); First column appears as literally &nbsp;. Second column shows up as a non breaking space. But, mostly, if you want to mess with html, you use the innerHTML property. It's a pain to use because outputting HTML is, 9 times out of 10, wrong. Any template system that doesn't do this gets a big point against it in my book, similarly to any database library that makes mixing unescaped text in the easiest way...) Anyway, their syntax is certainly brief. I can see the appeal in that. Curious though, how does haml handle forms? Looking through the documentation, it doesn't seem to at all. This is one of the nicest things about my DOM approach. You can write the form in standard HTML, with default values written there if you want, and the code will fill it in later.
 * SASS, generates CSS - http://sass-lang.com/ (I'm using the sass
 syntax and not the scss syntax)
Heh, I looked at that not long ago. I'm annoyed by CSS's lack of nesting. Not annoyed enough to introduce Ruby to the project, although I rather like what they did here. I'll probably spin my own version eventually.
 * CoffeeScript, generates JavaScript -
Eh, I thought about something along these lines, write some of it, but I decided against going far with it. There's two reasons: a) If you're writing enough Javascript to make using a replacement worth it, you're writing too much Javascript. b) Javascript's biggest problem is that it's loosely and dynamically typed, not that it's whitespace is ignored. The auto-generated javascript to access my D code make using it almost easy anyway http://arsdnet.net/cgi-bin/apidemo/javascript <button onclick=" CoolApi.getABox('green').appendTo('playground'); " type="button">Get a green box</button> Those are all basic examples. The idea is the server does most the work, and Javascript simply plugs it in somewhere in the document - the same way the page is built on the server side. appendTo's argument can be a string for a trivial ID or an element as returned by any of the built in browser functions (such as querySelector - no need to load up a big piece of shit like jQuery to have that.) The generic get() function does partial application so it's reusable with other functions: function fadeIn(parent, speed, html) { ... } CoolApi.getABox('green').get(fadeIn, this.parentNode, 10); Since the server might return data, such might not always work. That's where the format modifier comes in: CoolApi.getPeople(0).format('table').get(fadeIn, this.parentNode, 10); Thus, javascript functions become fairly trivial and/or reusable, so you don't have to deal with the language very much at all. I also toyed with generating Javascript from D: auto js = new ClientSideScript(); js.alert("Hello, world!"); js.var("wat") = 10; js.alert(js.wat); That kind of thing. Each method call to the js object builds a code string inside it. D variables passed as arguments are converted to Javascript literals and added to the code. It actually kinda works, and I use it from time to time, but only for little things. For the big, I don't think it's worth it.
May 15 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-15 19:15, Adam D. Ruppe wrote:
 Jacob Carlborg wrote:
 But that way you would need to declare different types of Options
 structs all over the place?
Sometimes, but most functions are fine with regular argument lists, to me, using enums for options where appropriate.
In Rails basically every view helper function takes two hashes of options, one related to the function and one for html attributes.
 I think there are other languages available that is far better than
 PHP that you could compare with instead. Ruby on Rails:
Come to think to fit, PHP's $_REQUEST() would have worked here too and shaved off a couple lines. Anyway, I've used Ruby before, but never Rails. The to_i and to_s things are familiar.. me forgetting to write them caused many problems in that project. I hate dynamic languages so much. That Ruby project is what put the nail in the coffin. I want to get an idea of how Rails works though, so see how well my approaches stack up. But, aside from discussions like this one, I haven't had a chance to get into it.
I think you really should give it a try. This is a good place to start: http://guides.rubyonrails.org/
 This will try to find a Post with the given id and automatically
 converted the given value to an integer.
This is similar to how my database libs work. It actually lets the database do the conversion though.
I don't know if it's rails or the database that does the conversion.
 I've been thinking for a while to try and create something
 similar as Rails' ActiveRecrod for D but every time I tried to do
 it turns out to work quite badly with a static type system.
Have you seen Piotr Szturmaj's Postgres code? http://www.digitalmars.com/d/archives/digitalmars/D/learn/D2_postgresql_interface_-_Phobos2_23693.html#N23695 (there's more posts than that on it too if you search) It might give you some ideas.
I probably have seen that post but since you have to manually specify the columns in a table I didn't like it.
 I went the other way; I don't mind writing SQL. (I always find
 automatic mappings the other way to be inefficient and lacking
 anyway.)
I really like how it works in Rails.
 As I said above, I don't see the big advantage if I have to use
 Variants all over the place .
The thing is it's not *all* over the place. There's a small area where you use them, and you get the static type benefits everywhere else. Even with the variant areas, the static type system helps a little bit. At least misspelled variable names are caught ahead of time by the compiler.
I guess you're right.
 HAML, generates HTML - http://haml-lang.com/
Syntax and indenting aside, concepturally, that's similar to how my DOM based code works. auto profile = holder.addChild("div").className("profile"); auto left = profile.addChild("div").className("left column"); left.addChild("div", print_date).id("date"); left.addChild("div", current_user.address).id("address");
Don't know why but I think this is verbose and it's more difficult to visualize how the HTML will look like.
 One big difference, semantically, is my code always escapes HTML
 by default. Looks like haml uses&= for escaping, while = does
 not.... so their homepage example is both incorrect and
 open to XSS attacks!
That depends on how it's configured. In addition to that Rails provides functions for escaping.
 (I offer two ways to write HTML: some functions take arguments
 of type Html, like Table.appendRow:

 table.appendRow("&nbsp;", Html("&nbsp;"));

 First column appears as literally&nbsp;. Second column shows up
 as a non breaking space.


 But, mostly, if you want to mess with html, you use the innerHTML
 property. It's a pain to use because outputting HTML is, 9 times
 out of 10, wrong. Any template system that doesn't do this gets
 a big point against it in my book, similarly to any database
 library that makes mixing unescaped text in the easiest way...)



 Anyway, their syntax is certainly brief. I can see the appeal in
 that.


 Curious though, how does haml handle forms? Looking through the
 documentation, it doesn't seem to at all.
With %from like it handles any other HTML tag ...
 This is one of the nicest things about my DOM approach. You can
 write the form in standard HTML, with default values written there
 if you want, and the code will fill it in later.
... but usually you use the "form_for" or "form_tag" helper that Rails provides: = form_for post do |f| = f.label :title = f.text_field :title In the above example :title have to be a column in the Post model. If the post instance has a title the text field will have the title as its value. There's also a plugin called "formtastic" that should make it even simpler (although I've never used it): https://github.com/justinfrench/formtastic
 * SASS, generates CSS - http://sass-lang.com/ (I'm using the sass
 syntax and not the scss syntax)
Heh, I looked at that not long ago. I'm annoyed by CSS's lack of nesting. Not annoyed enough to introduce Ruby to the project, although I rather like what they did here. I'll probably spin my own version eventually.
Then I think you should checkout LESS: http://lesscss.org/ Basically the same thing as SASS but without the Ruby dependency.
 * CoffeeScript, generates JavaScript -
Eh, I thought about something along these lines, write some of it, but I decided against going far with it. There's two reasons: a) If you're writing enough Javascript to make using a replacement worth it, you're writing too much Javascript.
I use coffeescript at work where we use the jqgrid library. It's basically a fancy table with inline editing, and it can do a whole bunch of other things as well. I have around 450 lines of coffeescript to control the grid the way we want to have it. We use a lot of custom cell views and cell formatters.
 b) Javascript's biggest problem is that it's loosely and dynamically
 typed, not that it's whitespace is ignored.
Well, I don't use CoffeeScript because it uses indentation for scoping. I use it for its other features. I don't know what I like best in CoffeeScript but I think it's the syntax for anonymous functions, just an arrow: ->. Another thing I really like is it's built in support for rebinding the "this" variable. In JavaScript if you use an instance method as a callback to an event function the "this" variable is now no longer the class instance, instead it's the object that raised the event. If you use => instead of -> in CoffeeScript it will rebind the "this" variable back to the instance making it behave all the other languages. It also has a class based object model which is then translated into the prototype model used by javascript.
 The auto-generated javascript to access my D code make using it
 almost easy anyway

 http://arsdnet.net/cgi-bin/apidemo/javascript

 <button onclick="
    CoolApi.getABox('green').appendTo('playground');
 " type="button">Get a green box</button>


 Those are all basic examples. The idea is the server does most the
 work, and Javascript simply plugs it in somewhere in the document -
 the same way the page is built on the server side. appendTo's
 argument can be a string for a trivial ID or an element as returned
 by any of the built in browser functions (such as querySelector -
 no need to load up a big piece of shit like jQuery to have that.)

 The generic get() function does partial application so it's reusable
 with other functions:

 function fadeIn(parent, speed, html) { ... }

    CoolApi.getABox('green').get(fadeIn, this.parentNode, 10);


 Since the server might return data, such might not always work.
 That's where the format modifier comes in:

    CoolApi.getPeople(0).format('table').get(fadeIn, this.parentNode, 10);



 Thus, javascript functions become fairly trivial and/or reusable,
 so you don't have to deal with the language very much at all.
Correct me if I'm wrong but that would require a request for bascially every function call? I don't like that, and I don't like the inline javascript.
 I also toyed with generating Javascript from D:

 auto js = new ClientSideScript();

 js.alert("Hello, world!");

 js.var("wat") = 10;

 js.alert(js.wat);


 That kind of thing. Each method call to the js object builds a
 code string inside it. D variables passed as arguments are
 converted to Javascript literals and added to the code.

 It actually kinda works, and I use it from time to time, but
 only for little things. For the big, I don't think it's worth it.
Ok. -- /Jacob Carlborg
May 16 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Jacob Carlborg wrote:
 I think you really should give it a try. This is a good place to start:
Cool, thanks!
 Don't know why but I think this is verbose and it's more difficult
 to visualize how the HTML will look like.
That's also a bizarre example... 9/10 times, my code looks more like: auto list = document.getElementById("items-holder"); foreach(item; items) list.addChild("li", item); than the longer thing. If you want to visualize the html, you usually want to look at the html file, since it contains the majority of the structure.
 but usually you use the "form_for" or "form_tag" helper that
 Rails provides:
That's not bad.
 Another thing I really like is it's built in support for
 rebinding the "this" variable
That's easy in Javascript too. It has the Function.apply method built in that makes it as simple as writing a higher order function. I find javascript is easier to use if you think of it as a functional language with procedural elements rather than an object oriented one.
 Correct me if I'm wrong but that would require a request for
 bascially every function call?
Most of them, yes (though calls being passed as arguments to other calls are combined0, but keep in mind a HTTP request does *not* have to go to the server! If your server side code gives the appropriate cache headers, the ajax responses are cached too. There's a good chance you have to hit the server anyway for db access too...
 I don't like that, and I don't like the inline javascript.
Inline javascript was done here for convenience. You're free to do it in a separate file just like any other script.
May 16 2011
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
So I'm writing the official PHP library to access my work library.

Just spent 20 minutes trying to figure out why it wasn't working
right.

The problem was ultimately here:

                $rurl .= "?" + $this->getArgString();

See the mistake? Neither did the stupid PHP interpreter. I hate it
so much.
May 13 2011
prev sibling parent reply Nathan <nchriste yahoo.com> writes:
This looks really interesting -- this will be obvious from my question -- I am a
hobbyist programmer interested in D (with most experience in Python).

I can get the first cgi example (not the mixin) to compile and run on an Apache
cgi server.

I cannot get the second, cgi/mixin sample to compile. What is the appropriate
dmd
command line?

If I write the text verbatim and compile as a module "modulename", I get three
errors, one for the function "run" indicating that "cgi" is not defined, did I
mean Cgi.  The other two errors say that "modulename.run" cannot be called with
argument type Cgi and that 0 arguments are expected for function type void --
and
these errors indicate the line number from the arsd/cgi.d module.

I'm sure this is something simple and that I'm not yet understanding mixins and
how to troubleshoot this type of error -- anyone want to point me to the nose on
my face?

Thanks!

Nathan
May 23 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
Nathan wrote:
 I cannot get the second, cgi/mixin sample to compile. What is the
 appropriate dmd command line?
First, download my cgi module http://arsdnet.net/dcode/cgi.d Then, in the same directory write this file, hello.d: === import arsd.cgi; void whatever(Cgi cgi) { cgi.write("Hello!"); } mixin GenericMain!(whatever); ==== And use this command line: dmd hello.d cgi.d Make sure you are using a recent dmd2 compiler like 2.053 from here: http://digitalmars.com/d/2.0/changelog.html You should get a program hello that, when run on the command line, outputs this: ===== Cache-Control: private, no-cache="set-cookie" Expires: 0 Pragma: no-cache Content-Type: text/html; charset=utf-8 Hello! ===== Copy it to a cgi enabled directory ( cgi-bin/ is preconfigured on most Apache installs) and you should be able to access it from the web: http://arsdnet.net/cgi-bin/test If it doesn't work, can you copy/paste the errors in here?
May 23 2011
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Also:

" other two errors say that "modulename.run" cannot be called with
argument type Cgi and that 0 arguments are expected for function type void "

When using the generic main mixin, the function you pass must
always take one argument: a Cgi object.

void yourFunctionHere(Cgi cgi) { }

When the mixin is compiled, it expands to something like this:


void main() {
   auto cgi = new Cgi;
   scope(exit) cgi.close();
   try {
        yourFunctionHere(cgi);
   } catch (Exception) {
        // log and maybe display the error then exit
   }
}


So the function you pass to the mixin is called with an argument:

        yourFunctionHere(cgi);


Which might be producing the error you saw, if your function
couldn't take the cgi object as it's own argument.




Why use the mixin at all? Writing main yourself might be simpler.

There's three reasons:

!) It saves you from writing the same thing over and over as your
   main function. This is a small benefit, but it's nice.

2) It can display errors to the browser in debug mode. This makes
   debugging easier. The message is right there.

3) This is the biggest one: if the main() function ever needs to
   change, your code doesn't.

Thanks to the GenericMain mixin, for example, you can switch to
using FastCGI or a built in webserver simply by recompiling with
a different version. None of your code has to change.
May 23 2011
parent Nathan <nchriste yahoo.com> writes:
Adam,

Thanks for the step by step guide.  My problem was exactly what you
outlined, that "yourFunctionHere" did not take Cgi cgi as an argument.
That's all I needed!

I definitely understand the benefit of the mixin -- the overall design
makes a lot of sense.

Nathan





On Mon, 23 May 2011 16:57:06 +0000 (UTC), Adam D. Ruppe
<destructionator gmail.com> wrote:

Also:

" other two errors say that "modulename.run" cannot be called with
argument type Cgi and that 0 arguments are expected for function type void "

When using the generic main mixin, the function you pass must
always take one argument: a Cgi object.

void yourFunctionHere(Cgi cgi) { }

When the mixin is compiled, it expands to something like this:


void main() {
   auto cgi = new Cgi;
   scope(exit) cgi.close();
   try {
        yourFunctionHere(cgi);
   } catch (Exception) {
        // log and maybe display the error then exit
   }
}


So the function you pass to the mixin is called with an argument:

        yourFunctionHere(cgi);


Which might be producing the error you saw, if your function
couldn't take the cgi object as it's own argument.




Why use the mixin at all? Writing main yourself might be simpler.

There's three reasons:

!) It saves you from writing the same thing over and over as your
   main function. This is a small benefit, but it's nice.

2) It can display errors to the browser in debug mode. This makes
   debugging easier. The message is right there.

3) This is the biggest one: if the main() function ever needs to
   change, your code doesn't.

Thanks to the GenericMain mixin, for example, you can switch to
using FastCGI or a built in webserver simply by recompiling with
a different version. None of your code has to change.
May 24 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"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() { // 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. 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.) 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.
May 12 2011
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
    // Read in HTTP request headers
Actually, that's not quite right. The HTTP headers are sent as environment variables. stdin gives you the POST variables - with the encoding given in the HTTP_CONTENT_TYPE envvar iirc. (that's where the Content-Type http header is found). The most common type is urlencoded, so it's just like parsing the query string. The other one I handle is multipart - the encoding for file upload forms. Getting all that stuff out is the main benefit of a basic cgi library.. it's a bit of a pain to do yourself every time.
May 12 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Adam Ruppe" <destructionator gmail.com> wrote in message 
news:iqhha9$17dp$1 digitalmars.com...
    // Read in HTTP request headers
Actually, that's not quite right. The HTTP headers are sent as environment variables. stdin gives you the POST variables - with the encoding given in the HTTP_CONTENT_TYPE envvar iirc. (that's where the Content-Type http header is found).
Ugh. Apperently, too much Flash/PHP/HTML/etc has rotted my mind...
May 12 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
 Ugh. Apperently, too much Flash/PHP/HTML/etc has rotted my mind...
Speaking of brain rot, the first version of my cgi.d actually aimed to mimic PHP! Some stupid part of me actually started to *like* the superglobals for a while... It had a static module constructor that built the arrays, and gave them global names like PHP does: import cgi; void main() { auto my_var = _POST["my_var"]; // works in D } It even simulated PHP's session_start() thing, though bugs in std.variant kept it from being particularly useful at the time. While std.variant is now fixed, I haven't had a need for sessions like that, so never updated that to the new module. For some reason, I actually liked it at the time. But, it broke down when I decided to write my own little http server to avoid Apache bloat for an app. A shared, mutable global is obviously nasty there. (I did stick with it for a while, but it got so complicated I ditched the whole stupid thing and started over, writing the new class based cgi.d. If you look at my code though, you'll see a couple things that are very bizarre according to the CGI standard: these are the things that let it work with the embedded httpd too. It reads all headers itself and writes the raw protocol to sockets instead of stdout when constructed that way. Thus, aside from the constructor arguments, the rest of the client code looks the same, so I can switch from embedded to apache/iis and back easily enough. The functions being mixin GenericMain!() instead of main() is also due to this, though the try/catch it provides is nice too.) Anywho. Another bad experience with PHP led me to make the get and post vars in cgi.d completely immutable - something that leads to some pain, since phobos and druntime don't care much for immutable(char[])'s (instead opting to work with immutable(char)[]'s. This has gotten worse in the new beta with even the replace() function no longer working on the former! Ugh!) But, some minor hacks here and there make it work, so yay. And, unlike PHP, if some asshole decides to write $_POST["evil"] = $whatever; in his vile function, I won't have to deal with it later! Whoo hoo!
May 12 2011
parent "Nick Sabalausky" <a a.a> writes:
"Adam D. Ruppe" <destructionator gmail.com> wrote in message 
news:iqhkdn$1co1$1 digitalmars.com...
 Ugh. Apperently, too much Flash/PHP/HTML/etc has rotted my mind...
Speaking of brain rot, the first version of my cgi.d actually aimed to mimic PHP! Some stupid part of me actually started to *like* the superglobals for a while...
Heh. Well they are at least convenient. I'm sure that's probably why PHP did it in the first place.
 It had a static module constructor that built the arrays, and gave
 them global names like PHP does:

 import cgi;

 void main() {
     auto my_var = _POST["my_var"]; // works in D
 }

 It even simulated PHP's session_start() thing, though bugs in
 std.variant kept it from being particularly useful at the time.
 While std.variant is now fixed, I haven't had a need for sessions
 like that, so never updated that to the new module.
I don't know how yours works, but PHP's session system has a number a pains. The whole way it handles session timeouts is just bizarre, and the fact that it's even possible for the sysadmin to enable session.auto_start has caused me big headaches. Actually, that get's into one of the big things I hate about PHP: there's far too much it allows sysadmins to fuck with. And it's not always possible for the programmer to override dumb php.ini settings. As a result, even a single specific point release of PHP is essentially 5 million different languages, depending what server you're on and your sysadmin's day-to-day whims. And a lot of the settings are just stupid features that never should have been put in in the first place (granted, those ones tend to become deprocated, but by then the damage is already done). Which reminds me of the PHP4->PHP5 debacle. I can certainly appreciate the occasional need for changes that break backwards-compatibility (especially as a D user), so I don't have a problem per se with the fact that PHP5 broke backwards compatibility (although it's not like compatibility in PHP has ever been anything but a joke). But there are so many ways it would have been so trivial to avoid the problems it caused. Probably the simplest and most obvious would be a decree "Scripts targeting PHP5 and up must end with the extension .php5, otherwise it will either refuse to run or get sent to a PHP4 installation if available." Or instead of the extension, require the first line to be "<?php PHP5...", etc. So many easy ways to avoid the problems they had. And that's all just off the top of my head. But PHP's primary design principle seems to be "Be sloppy whenever possible." Of course, D2 broke backards compatibility with D1 and doesn't have anything like what I suggested above for PHP5. But it works for D because the language exists completely on the development side, not on the server side like PHP.
 For some reason, I actually liked it at the time. But, it broke
 down when I decided to write my own little http server to avoid
 Apache bloat for an app.
Cool :) It's amazing how simple a basic http server is. Yea, there's some details and gotchas to be careful of if you're really trying to follow the HTTP1.1 spec properly (which is probably a good idea anyway). But even still, someone who's never written a server would probably think it would need to be some major Apache-level undertaking. That's what I originally thought. But unless you're really going for super-flexibility/configurability/bells-and-whistles, etc., you really don't need 99% of that, and it actually ends up being pretty simple. ...Unless you want to run it on a shared web host. Then you're just plain shit-out-of-luck ;)
 A shared, mutable global is obviously
 nasty there.

 (I did stick with it for a while, but it got so complicated I
 ditched the whole stupid thing and started over, writing the
 new class based cgi.d. If you look at my code though, you'll see
 a couple things that are very bizarre according to the CGI standard:
 these are the things that let it work with the embedded httpd too.
 It reads all headers itself and writes the raw protocol to sockets
 instead of stdout when constructed that way. Thus, aside from the
 constructor arguments, the rest of the client code looks the same,
 so I can switch from embedded to apache/iis and back easily enough.
That's pretty cool.
 The functions being mixin GenericMain!() instead of main() is also
 due to this, though the try/catch it provides is nice too.)


 Anywho.

 Another bad experience with PHP led me to make the get and post
 vars in cgi.d completely immutable - something that leads to
 some pain, since phobos and druntime don't care much for
 immutable(char[])'s (instead opting to work with
 immutable(char)[]'s. This has gotten worse in the new beta with
 even the replace() function no longer working on the former! Ugh!)

 But, some minor hacks here and there make it work, so yay.

 And, unlike PHP, if some asshole decides to write $_POST["evil"] =
 $whatever; in his vile function, I won't have to deal with it later!
 Whoo hoo!
Yea, D kicks the snot out of PHP in so many ways. It's so unfortunate though that shared web hosts have SOOO much better support for PHP than native-compiled CGI. I suppose one could argue that's for security and reliability reasons, but PHP's known for being terrible in those areas, too. *shrug* Just a popularity thing I guess...It annoys me to no end that the computer world has become every bit as trend-driven as the high-fasion industry...I guess that's what happens when you let middle managers in on things.
May 12 2011
prev sibling parent reply Matthew Ong <ongbp yahoo.com> writes:
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
May 19 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
 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...
That's such backward nonsense I find it hard to believe anyone would seriously believe it.
May 19 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Matthew Ong" <ongbp yahoo.com> wrote in message 
news:ir3anp$dgj$1 digitalmars.com...
 On 5/13/2011 4:01 AM, Nick Sabalausky wrote:
 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...
What's wrong with it? This is the first I've heard of any such issue.
 {
      // 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.
Actually, like Adam pointed out, I got the HTTP request headers part completely wrong. HTTP headers come from environment variables, and stdin is just used for any data that's been posted. So that part's totally wrong. So you'll want to just rip that part out like this: // hellocgi.d import std.conv; import std.stdio; void main() { // 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>"); }
 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.
First I've heard of it. What's the problem?
May 19 2011