Nitrogen Templates or Not

92 views
Skip to first unread message

LRP

unread,
Apr 2, 2009, 8:11:11 AM4/2/09
to Nitrogen Web Framework for Erlang
This post extends the Nitrogen Thoughts thread with the hope that it
opens a wider context and deeper discussion.

In my blog, pockingarounderlang.wordpress.com, I've been exploring a
number of Erlang web frameworks.

One thing that strikes me is the wide gulf between the example page
makeups provided (if any) and nearly any popular site you would see
on the web today.

Take a look at:

http://nytimes.com/
http://www.amazon.com/
http://www.hp.com/#Product

Now one could argue that once you have <h1>Hello, World</h1>,
everything else is just more of the same. But I'd argue not. If you
look more carefully, you'll see that these pages are made of grids
with different functionalities across the panels. Some of these
functionalities are going to carry over to other pages. Some operate
across two panels; e.g. menu and item functionality. Some would be
functionally useful across many different sites.

For these kinds of sites, there's strong argument for easing the
professional designer's task in every way possible with simple
templates. But that's not really where I want to go here.

If I could wave a wand over Nitrogen, my spell would result in a
system that works something like this:

A page is specified as a list of calls into a collection of plug-ins,
mini-applications, applets, or whatever we wish to call them. Let's
call them aps.

Aps provide specific functionality; as simple as a block of text, or
as complex as a stock trading mechanism.

Aps can be mixed and matched on the page

Each ap would be able to call on site-level, page-specific content
files.

Each ap would be displayed as a panel in the overall page grid, most
likely as a named div.

Thus, each ap would have an associated CSS mini file with both hard-
wired specs and variable slots that can be filled by a master CSS
file.

Aps have the following properties:

a) Each ap is a black box so far as the page makeup code and other aps
are concerned, with three exceptions

- The interface that calls the ap; e.g. the term in the page-makeup
list
- A mechanism that enables a link in one ap to call up a display state
within another ap; e.g. menu item that calls a news item
- A deeper interface or include mechanism that makes it possible to
build on an ap to create a more specialized ap; e.g. an image-plus-
caption ap that builds on the image and text block aps

b) Over the duration of a given connection, each ap would maintain its
own state

c) Aps would be constructed around explicit interface standards and
specifications so that competent Erlang programmers can add to the
collection of available aps.

This is no doubt a far departure from the current architecture of
Nitrogen. And I'm not qualified to judge whether or not it fits within
the outer boundaries of Nitrogen's conceptual model. But I do believe
that it's a realistic way to develop modern, sophisticated web-pages
with a relatively high degree of productivity.

My understanding is that Django was designed with this kind of
complex page drawing upon a division of labor across techies, content
people, and designers from the beginning.

If nothing else, I believe that this vision raises the following
question for Nitrogen:

When developed to full potential, where will Nitrogen fit across the
universe of site developers?

a) Of value only to one-man-band development shops?
b) Of value only to large shops employing teams of specialists?
c) both/and?

In other words, will Nitrogen be a scalpel, a power saw, or a Swiss
Army knife?

All the best,

LRP

Jon Gretar Borgthorsson

unread,
Apr 2, 2009, 9:33:21 AM4/2/09
to nitro...@googlegroups.com
So basically you want the grand daddy of web frameworks, WebObjects.
Just not in Java or Objective-C. :)

vijaykandy

unread,
Apr 2, 2009, 3:58:29 PM4/2/09
to Nitrogen Web Framework for Erlang
> If nothing else, I believe that this vision raises the following
> question for Nitrogen:
>
> When developed to full potential, where will Nitrogen fit across the
> universe of site developers?
>
> a) Of value only to one-man-band development shops?
> b) Of value only to large shops employing teams of specialists?
> c) both/and?

You are comparing apples to oranges. The sites you listed above are
developed (or can be developed) using web content management systems,
used to manage and render dynamic web material. If your intent is to
build a CMS website, there are plenty of CMS frameworks on the web.
See Joomla, Drupal etc. I wouldn't choose Erlang for that purpose.
Managing sites like that is mostly done via an admin interface and
rarely by programming or updating code. There are also portal
frameworks which serve that purpose very well. You could add small
apps (portlets) and create pages or content. Again, little programming
needed there.

I'd like to compare Nitrogen to frameworks like Struts, Spring MVC,
Spring.NET etc., which are used to build websites that provide
software as a service - which is done chiefly by programming, whether
its by 1-man team or by a team of specialists. You could build a CMS
site with Nitrogen (or with Struts, Spring etc. for that matter) but
that would be like opening a can with a screw driver.

Anyone who has built apps using frameworks in Java, .NET or even PHP
can see how building an app using Nitrogen is a breeze.

Tom McNulty

unread,
Apr 2, 2009, 4:13:29 PM4/2/09
to nitro...@googlegroups.com
Hi,

If I'm understanding correctly, the desired functionality you require
from such a system is already present.

Templates as they stand, allow you to render content from arbitrary
modules. To compliment this, event callbacks may be delegated to any
specific module. This permits you to build mini-components, that can
function on any given page.

For instance I built a simple login form 'component' which I include
on all my pages. The login component has simple logic, to control the
way it renders itself depending on whether the user is logged in, or
not. If a user/password is submitted, it's received by the login
module for processing.


Is this what you mean by mini-application?


- Tom

LRP

unread,
Apr 2, 2009, 11:26:18 PM4/2/09
to Nitrogen Web Framework for Erlang
Thanks all for responding to my daydream.

Tom:

That's exactly what I have in mind! Given that, how can I help slow-
learners like me learn how to write such components for Nitrogen,
encourage all to do so, and to make them easily available to the
Nitrogen community?

Vjaykandy:

Thanks for helping to put Nitrogen in perspective.

I developed a large many-featured conference management system over
some 12 years in... Cold Fusion. Talk about screwdrivers and soup
cans.

But at the time we started, the only viable choices were perl,
Microsoft's ASP, and Cold Fusion. I didn't know perl, wasn't fond of
Microsoft, and Cold Fusion looked easy to learn. As the years went by
with non-stop bombardment of requests for new features and
functionality changes we remained so stuck with CF that I never had a
chance to look into Java or PHP. Besides, all those parens in Java
gave me the jitters.

I'm sure you're correct that building an app in Nitrogen is a breeze.
That's one thing of several that draws me to it. I haven't yet been
able to spend much time with it, but so far I don't quite catch the
hang of it. Thus, I'm hoping for more user documentation soon and
willing to help wherever I can.

Jon:

WebObjects... never met the fellow.

Once again, I heartily appreciate the input.

Best wishes,

LRP

Vijay Kandy

unread,
Apr 3, 2009, 4:35:56 PM4/3/09
to Nitrogen Web Framework for Erlang
Hello Tom,

Can you elaborate a bit more on how you can add a "component" in all
pages? Create a region in a template and dynamically populate HTML in
the region .. is that how you did this or is there a better way? If
possible, I'd like to keep HTML out of erl files.

Regards,
Vijay

Tom McNulty

unread,
Apr 3, 2009, 6:51:42 PM4/3/09
to nitro...@googlegroups.com
Hello,

Sure I can post something in a bit more detail when I get to my
machine. In the meantime, I think the "View Source" and navigation bar
from the Quickstart app can serve as a good example of this. I'll
post the login component though, as it demonstrates how events can be
handled as well.

- Tom

LRP

unread,
Apr 3, 2009, 11:22:22 PM4/3/09
to Nitrogen Web Framework for Erlang
Nitrogen Parts

Please bear with my flight of fancy. If I stumble, please pick me up
and show me the error of my ways. If you see a way to further these
ideas, please jump in and make them stronger.

Nitrogen Parts are components as fantasized in my Nitrogen Templates
or Not post and, perhaps, similar, to the functionality described by
Tom McNutty.

We could call Parts Components, Portlets, Applets, or anything else we
please, but Parts, to me, is simple, descriptive and, so far as I
know, unique in usage.

Parts are single-function; e.g. each does one thing and does it well.

My intuition tells me that the Parts infrastructure could largely be
build as a layer above Nitrogen, though Parts could well use existing
Nitrogen techniques and code. But I'm not familiar enough yet with
Nitrogen to say that with assurance.

Ideally there would be a cataloged archive of open-source, tested, and
vetted Parts somewhere on the web, but this is sugar rather than
necessity.

Each Part is installed in it's own directory tree identified by the
name of the root directory.

The Part would be registered with the application when imported into
the application directory tree.

Parts could be thought of as another incarnation of the "behaviours"
concept in Erlang.

Each Part would have the following layers/functionality:

Base Interface -- some kind of compile-time include mechanism to allow
specialization of more basic Parts

Core Logic -- implements the functional behavior of the part,
including bare-bones display, business logic, and data persistence.

-- I'm assuming that some parts will have display only behavior and
some will have get user input/display result behavior, perhaps in the
form of a state machine cycling through several states.

-- I'm also assuming that some elements of the display layout, as well
as labels and some prompts may be "hard-wired," though modifiable by
programmer.

-- Whereas some elements, usually text, in the display layout can be
modified as configuration data.

-- I don't know how Lab View components work, but I'm thinking along a
similar line.

-- The data persistence functionality may take the form of an
interface to db of choice.

Site-Level Configuration Data

Page-Level Configuration Data

Styling Data

-- I'm guessing that most styling decisions would be determined higher
up in the page make-up/run-time cycle. Thus, the styling choices at
the Part level may be fairly limited or, perhaps, satisfied through
defaults.

-- Styling Data could be consolidated across the Parts that make up
each page through some kind of compile process.

-- Again, some styling tags may be hardwired, some configurable

-- Styling could possibly be bifurcated into site-level and page-
level; e.g. site-level styling is constant across the site; page-level
modifies styling for requirements of a specific page

-- Styling and Configuration Data could be further segmented to
support multiple independent instances of a Part on a page.

Control Interface -- a protocol for interaction with other Parts on
the same page

-- Think of a link in one Part that controls the display state of
another.

State Interface -- a protocol for interaction with whatever mechanism
is maintaining connection state. Thus, user could link to another
page, then return to find state preserved.

Page Makeup Interface -- a protocol for mapping a Part into a page.

Vijay Kandy surmised that we're talking about a full-blown content-
management system here. My take is that a content management system
could be built on top of Parts but, in the short term, I'm quite happy
to enter configuration data into files through a text editor. I'd
advocate in version 1.0 and below of Parts that simplicity be the
guiding virtue.

Once I've seen Tom McNutty's implementation of his log-in component,
perhaps I can see/show more explicitly how Parts might work; maybe
even cobble up a prototype.

But, I have much to learn before I can do so with confidence.

Many thanks,

LRP

Rusty Klophaus

unread,
Apr 4, 2009, 9:47:19 AM4/4/09
to nitro...@googlegroups.com
Hi LRP,

I always appreciate a good thought experiment.

Let me repeat what I heard from you...

Nitrogen Parts

1. Allow the encapsulation of a "mini application".
2. Are modular and shareable.
3. Contain their own visual interface and back-end logic.
4. Could be responsible for persisting their own data.
5. Are stylistically sandboxed so that styling of one does not affect
the other.
6. Can talk to each other.
7. A page containing parts can modify the visual interface or backend
logic through configuration properties or injected functions.
8. A user can navigate away from a parts page, navigate back, and the
state remains.

Does this capture everything? Please let me know if I have
oversimplified things here. When talking about technology, it's very
easy to say "Bah! Who needs <Awesome New Thing>. Assembly language
does everything I need." This is where a face-to-face chat with
whiteboard and markers would be helpful. :)

For the most part, Nitrogen Elements fill #'s 1, 2, 3, 4, and 7 above.
Admittedly, there are no clear, illustrative samples online, but you
can see some complex examples if you look at the inplace_textbox or
wizard controls in the Nitrogen source code. Tom McNulty's login
example should further illustrate the concept. The key to unlocking
this support is to set the delegate attribute on your #events. The
delegate attribute will cause an event to fire back to a
DelegateModule that you specify rather than the page itself. Very
simple, very powerful.

An addendum to #2, Nitrogen Elements are certainly not as shareable as
they could be. We really need a widely adopted Ruby Gems like system
for Erlang. Someone go make that happen, and figure out how to deal
with module naming collisions in the process. :)

#6 is interesting, as Nitrogen does not currently let elements talk to
each other. Currently, things only happen when a user clicks/drags/
mousesover/types something on a page, and then the event goes either
to the PageModule or a DelegateModule, which can then update the page.
This is where more thought needs to happen, and more work needs to be
done.

#5 will require some dirty hacks to happen automatically, as it goes
against the grain of HTML. You can do this easily enough manually
through the proper use of CSS classes.

#8 would require URLs with a bunch of extra crap on the end, which
looks gross, or heavy use of sessions, which decrease scalability. As
it is now, ALL of a page's state is stored on the page itself (or more
accurately, in Javacript variables) and the state is shuttled back and
forth and updated on each postback.

Along a slightly different train of thought, I feel like you might
have some new ideas about how Parts should actually placed on a
Nitrogen page? I would be interested to hear more about what you think
there. In your view, is a page still made up of a module? Is it a
configuration file? Maybe a parsed template?

Anyway, I already have some ideas for #6 floating around my brain.
They are part of a new (and very exciting) Nitrogen feature on the
horizon. Let's just say it will let Nitrogen do something that that no
other web framework can do.

Best,
Rusty

mats

unread,
Apr 4, 2009, 10:46:26 AM4/4/09
to nitro...@googlegroups.com
After reading #6 – I think the reddit team solved it by using a css compiler, that can handle variables, functions and nested styles. On slide 29 [1] they are talking about the C55 compiler. I don't say it's the right solution. Just FYI. (It's not out yet, but it will be open source.) It could be the most complicated solution to sandboxed  css. :)

I really like the atmosphere on this list, and it is exciting to see what is coming out next. Good work to the team!

/m

[1] http://blog.reddit.com/2009/04/ride-snake-reddits-pycon-09-keynote.html
--
"One day I'll need to seriously force myself to get used to the stack-based programming, because every time Slava posts something, it's about some crazy shit he did in a few hundred lines that would take thousands in C or Java. That Factor gang is definitely doing something right." - gnuvince

mats

unread,
Apr 4, 2009, 11:50:00 AM4/4/09
to nitro...@googlegroups.com
ops.. #5

Tom McNulty

unread,
Apr 4, 2009, 3:14:45 PM4/4/09
to nitro...@googlegroups.com
As requested, here is how I handled a login box. Nothing fancy, I hope it lives up to the expectation ;)  As rusty mentioned, the magic is in the delegate. LRP you wanted to keep HTML out of erl files. I can see how this applies when you have large paragraphs of content that you wish others to edit, but for the example below the HTML is actually best suited inside erl files, so that it may be A) generated dynamically B) abstracted away from the rest of the page content. All styling is handled through external CSS.

In general I tend to favor simple frameworks that allow me to create what I need using basic constructs. As opposed to complex frameworks which provide support for adding pre-built components simply. A long time ago I tried a Java web framework called 'Tapestry'. The amount of 'plumbing' to create generic components was in some cases more extensive than the feature itself, it wasn't long before I just gave up on it. And of course, the more specific your component is, the less likely it's of use to others. 

Here's the final product. Nothing really interesting here.

 

In my template:

<div id="loginForm">
   [[[loginbox:display()]]]
</div>


loginbox.erl:

 1 -module(loginbox).
 2 -export([display/0event/1]).
 3 
 4 -include_lib("nitrogen/include/wf.inc").
 5 
 6 
 7 
 8 display() ->
 9     case wf:role(memberof
10         false -> draw_loginbox();
11         true -> draw_logout()
12     end.     
13     
14    
15 draw_loginbox() ->
16     Content = [
17         #textbox{
18             id=userLoginBox
19             next=passwordLoginBox},        
20         #password{
21             id=passwordLoginBox
22             next=loginButton},
23         #button{id=loginButtontext="Login"}
24     ],
25     wf:wire(loginButton#event { type=clickdelegate=loginboxpostback=login}),    
26     wf:render(Content).
27     
28     
29 draw_logout() ->
30     Content = #button{id=logoutButtontext="Logout"},
31     wf:wire(logoutButton#event{type=clickdelegate=loginboxpostback=logout}),
32     wf:render(Content).
33     
34     
35 event(login->
36     [User] = wf:q(userLoginBox),
37     [Pass] = wf:q(passwordLoginBox),
38     case cf_account:authenticate(UserPassof
39         denied ->
40             %errorbar:now("Sorry, Incorrect Name/Password");
41             ok;
42         {accepted_Account} ->
43             % forward to the secret illuminati material
44             ok
45     end;
46 
47 event(logout->
48     wf:clear_session(),
49     wf_redirect:redirect("/").




- Tom

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Nitrogen Web Framework for Erlang" group.
To post to this group, send email to nitro...@googlegroups.com
To unsubscribe from this group, send email to nitrogenweb...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/nitrogenweb?hl=en
-~----------~----~----~----~------~----~------~--~---


ll...@paisite.com

unread,
Apr 4, 2009, 11:48:40 PM4/4/09
to nitro...@googlegroups.com
Hi Rusty,

Happy as a kid in pie that you're on the case.

Nitrogen Parts

1. Allow the encapsulation of a "mini application".

Yes

2. Are modular and shareable.

Yes

3. Contain their own visual interface and back-end logic.

Yes

4. Could be responsible for persisting their own data.

Yes

5. Are stylistically sandboxed so that styling of one does not affect
the other.

Styling could be tricky, but maybe not necessarily so. Probably a matter of how the style tags are factored and named.

- Imagine a control with prompts, labels, input boxes, a submit button (if people still use these things) and, perhaps, a reset buttons -- a simple form.

Some style tags dictating the relative positioning and sizing of these elements are probably best left to hard-wired style tags; e.g. just to maintain the integrity and coherence of the form layout. On the other hand, we may want the page designer to specify the tag for the background and font color independently of the rest of the page, while the border type and width tags are controlled by a master page style sheet.

As you know, the cascading feature of CSS should make this fairly easy to accomplish. The trick is for the Part designer to decide which tags are hard-wired, and which can be configured by the page designer and at what level.

Seems to me that all this should be fairly easy to achieve if each part is enclosed in it's own named DIV.

6. Can talk to each other.

Yes, but not sure we need to go much further with this than allowing a link in one Part to link to a specific display state of another Part. For example, a user can click on a link in a menu of conference speakers, which is display by one Part in the page grid to call up a photo and bio of the speaker for display by another Part in another panel of the page grid.

7. A page containing parts can modify the visual interface or backend
logic through configuration properties or injected functions.

I'm not sure what you mean by this. We'd most certainly want Parts to able to call functions in the back-end logic I'd think. I can't think of why we might want it to work the other way but there may well be.

8. A user can navigate away from a parts page, navigate back, and the
state remains.

Yes

Does this capture everything?

In essence, yes, yes, yes!

Think of it this way, designing a page is like selecting ICs for bin of parts and plugging them into a prototype or circuit board. Each IC may need a bit of surrounding circuitry, in our case, some site-specific prompt language, an image file, or some site, page, or instance-specific styling.

Once the parts are selected and configured at page design time, then the page display logic becomes largely a matter of walking down a list.

> For the most part, Nitrogen Elements fill #'s 1, 2, 3, 4, and 7 above.

Rusty, you are fast becoming my Hero of the Year. And I'm sure you know that you already stand high on my list.



> Admittedly, there are no clear, illustrative samples online, but you
> can see some complex examples if you look at the inplace_textbox or
> wizard controls in the Nitrogen source code. Tom McNulty's login
> example should further illustrate the concept. The key to unlocking
> this support is to set the delegate attribute on your #events. The
> delegate attribute will cause an event to fire back to a
> DelegateModule that you specify rather than the page itself. Very
> simple, very powerful.

A second key, I think, is an explicit set of conventions/protocols/architectural specifications, what have you, that make the Parts as interchangeable and sharable as possible, while still giving the application designer flexibility in morphing the functionality of the Part to his/her specific needs and the page-designer sufficient flexibility to integrate a set of Parts into a page so that they look like they belong together.

A third key might be factoring common functionality across Parts in such a way that a relatively small set does, say, 80% of what we might want to do on a page, while providing a foundation for building ever more specialized Parts that can make a site or web application truly distinctive and special.

If this works the way I hope it would greatly benefit the application developer, the content providers, and the page designer without comprising anything a one-man-band might want to do. The application designer is saved from reinventing the wheel over and over again; freed to concentrate on just that 20% of new stuff that's most interesting and challenging. The content providers and page designers can mix and match parts to create exciting, page designs rich in functionality, working with familiar, consistent elements of great expressive and functional power.

I can imagine a set of Parts that, taken together, would make it very easy to create a fully customized web store, including product display, check-out, shipping, payment, and traffic-auditing modules, admin stuff, etc. (Ah, I can see here where data exchange/coordination between Parts may be more involved than I suggested above. Nothing like a good example to clarify your thinking.)

> An addendum to #2, Nitrogen Elements are certainly not as shareable as
> they could be. We really need a widely adopted Ruby Gems like system
> for Erlang. Someone go make that happen, and figure out how to deal
> with module naming collisions in the process. :)

Are you suggesting an on-line archive of Parts? Maybe developing a set of Parts to implement such a resource would be a good place to start. I'd imagine that with careful factoring, many of the Parts would be quite useful in other applications and other contexts.

> #6 is interesting, as Nitrogen does not currently let elements talk to
> each other. Currently, things only happen when a user clicks/drags/
> mousesover/types something on a page, and then the event goes either
> to the PageModule or a DelegateModule, which can then update the page.
> This is where more thought needs to happen, and more work needs to be
> done.

I trust that you and other Nitrogen wizards are fully up to the task. One day, sigh, I hope I can jump in and help. Maybe we can devote some brainstorming time at Erlang University.

> #5 will require some dirty hacks to happen automatically, as it goes
> against the grain of HTML. You can do this easily enough manually
> through the proper use of CSS classes.

Probably need to run through a number of prototypes to get it right.

> #8 would require URLs with a bunch of extra crap on the end, which
> looks gross, or heavy use of sessions, which decrease scalability. As
> it is now, ALL of a page's state is stored on the page itself (or more
> accurately, in Javacript variables) and the state is shuttled back and
> forth and updated on each postback.

Yes, I worry about this; wonder if connection-specific processes might be a way to go. But my experience is too limited to really weigh in. Actually, it was this problem that first got me thinking seriously about Erlang for some of the stuff I'd like to do.

When I developed a system somewhat along these lines in Cold Fusion for my conference marketing/management system I relied on ugly URLs and some code to more or less automate their formation and management. Actually, two different mechanisms since Cold Fusion forced me to manage URL and POST variables in somewhat different ways. It was all an ugly hack I assure you. Developing some conventions for naming the state variables helped a bit.

> Along a slightly different train of thought, I feel like you might
> have some new ideas about how Parts should actually placed on a
> Nitrogen page? I would be interested to hear more about what you think
> there. In your view, is a page still made up of a module? Is it a
> configuration file? Maybe a parsed template?

How about a simple text list of Parts that gets fed to a page-display controller function? I do something like this in the Python framework that drives my manga, ayatakeo.com. Works great; no idea how it might or might not scale.

> Anyway, I already have some ideas for #6 floating around my brain.
> They are part of a new (and very exciting) Nitrogen feature on the
> horizon. Let's just say it will let Nitrogen do something that that no
> other web framework can do.

Rusty, did I tell you that you are my hero?

All the best,

Lloyd


ll...@paisite.com

unread,
Apr 5, 2009, 12:37:06 AM4/5/09
to nitro...@googlegroups.com
Hi Tom,

> As requested, here is how I handled a login box.

Many many thanks for posting this.

> LRP you wanted to keep HTML out of erl files.

Actually, it was Vijay Kandy who expressed concerned about HTML in erl files. For my part, I'm agnostic, since I'm too naive to understand the implications.

I do have a sense that HTML will be essential inside the Part, whether in an erl file or not. For one thing, I think Parts should be enclosed in named DIVs to provide flexibility with discipline in styling. And I can see how HTML and some styling tags would be necessary inside a Part to maintain layout integrity.

Please see my most recent post to Rusty for a few more thoughts on the matter.

> In general I tend to favor simple frameworks that allow me to create
> what I need using basic constructs. As opposed to complex frameworks
> which provide support for adding pre-built components simply.

I totally agree re: simplicity. But it seems to me that the Nitrogen framework can be kept relatively simple. And each Part can be build using basic constructs as far as possible, striving for the greatest possible simplicity consistent with its inherent functionality. Each Part, moreover, should be built under a consistent set of interfaces with other Parts and the Nitrogen framework itself. In other words, if functional complexity is inherent in the Part, it should be encapsulated within the Part.

This, then, would push complexity from the Nitrogen framework off into the individual Parts. As a developer you can be highly productive while working within a simple, consistent framework while delivering ever more sophisticated functionality simply by adding additional Parts to the catalog.

But, I'm with you all the way in this regard, if it turns out that these ideas threaten to compromise the essential elegance of Nitrogen, then I'd be first to say bag 'em.

Tad of background...

I spent a whole bunch of years working with another programmer to build, enhance, and maintain an amazingly full-functioned web-based conference marketing/management system that supported world-class technical conferences around the world.

Our direct liaisons with our primary client were marketing managers who just happened to turn over every year. Each new crop was forever demanding new functionality and changes in existing functionality. We were constantly under intense, immutable deadlines. Hardly even time to test, and no time to document or step back to think about what we were doing.

You can imagine how ugly the code grew over time. We were forever dropping good code off the edge of the table while reinventing the wheel to do something ever so slightly different. Aged me before my time.

A system somewhat along the line of Parts is what we came to in later years. Implementation was ugly as hell under Cold Fusion, partly due to the language, but largely because we were still feeling our way. But it more or less worked. We started to see notable increases in productivity.

I cobbled up a crude next gen as my first Python project. It now drives my web manga, ayatakeo.com. Other than ugly learning curve code, the whole system is very simple in its fundamentals. I looked at it recently and saw that it could be ten times simpler yet.

> Nothing really interesting here.

Quite the contrary. I nominate your login box as the starting point for the very first entry in our official Nitrogen Parts catalog.

Best wishes and thanks again,

Lloyd


mats

unread,
Apr 5, 2009, 4:09:31 AM4/5/09
to nitro...@googlegroups.com
+1

"I totally agree re: simplicity."

-1
for the concept of configuration file. God help me, if ever have to
work in a configuration file.

ll...@paisite.com

unread,
Apr 5, 2009, 10:00:17 PM4/5/09
to nitro...@googlegroups.com
Hi, Mats,

> for the concept of configuration file. God help me, if ever have to
> work in a configuration file.

Yes, configuration files can be a pain. Can you suggest a simpler alternative?

Best wishes,

LRP


mats

unread,
Apr 6, 2009, 5:23:56 AM4/6/09
to nitro...@googlegroups.com
That was just a feeling. I realize we need a mechanism for pulling out
configuration data. What if we use erlang records in a simple erlang
module? Records can handle hierarchal data. Is that possible? What
make nitrogen great, is that it's almost a programmable configuration
file.

List of subjective points that make me think there is a better way.
1. Compilation don't verify syntax of configuration file.
2. Learning about a new syntax take time.
3. Configuration files trigger a context switch in the brain, which take time.
4. Things that isn't programmable make people feel powerless.

Later we can build a sensing module that only ask for configuration,
that the module can't guess or compute. (the NitrogenAI is alive)
*not serious* :)

ll...@paisite.com

unread,
Apr 6, 2009, 2:12:32 PM4/6/09
to nitro...@googlegroups.com
Hi there, Mats,

I certainly agree with everything you say.

Maybe the way forward is to cobble up a straw-man Part, examine configuration requirements, then brainstorm/prototype alternative configuration mechanisms.

No doubt we'll never satisfy every need for every user, but if we keep simplicity as a touchstone, can we go far wrong?

As to the straw-man Part, I'd suggest some kind of CRUD interaction since they're so common across web applications.

Configuration would involve at minimum:

- integration of Part into page grid
- prompting
- styling

If we need more site-developer/designer discretion, we might also wish to configure:

- db interface
- form field layout
- presentation of results
- etc?


> What if we use erlang records in a simple erlang module? Records can handle hierarchal data. Is that possible?

I'm not experienced enough to judge. Don't know why, but there seems to be lots of bitching about records throughout the Erlang community, but Rusty seems to use them effectively in current rev of Nitrogen.

I do know that specification of a page grid requires hierarchy, e.g. DIVs within DIVs.

The Python framework I cobbled up for ayatakeo.com employs stripped down CSS which is first appended in the header CSS specifications, then interpreted in the body to set up the DIVs and to call the plug-in "Parts."

My reasoning is that this requires little to no new knowledge on part of the web developer/designer. It also makes it a breeze to mix and match different page grids with the same content.

Down side is that it does require some amount of interpretation to generate the body. Nor does it deal with content or logic configuration of the "Parts" themselves.

I based my Python work on Karrigell, a very simple Python framework. Karrigell has an "include" function, which makes it dead easy to bring content into a "Part" as simple text files which can be edited by a javascript text editor.

I also brought in site configuration parameters this way, but wrote CRUD functions to edit them. This was the hackiest part of my system, mainly because I was learning Python as I went along. I now realize that with the proper set of "Parts," even this would be reasonably clean and easy.

See example page grid, page variable specification, and part content files below.

All the best,

Lloyd

******** page grid specification from LRP's Python "web framework" **********


DIV.Masthead {width: 100%;
clear: none;
float: none;
}

DIV.ma1 {width: 100%
}

DIV.ma11 {
}

/* /div */
/* /div */
/* /div */

DIV.bannerMenu {width: 100%;
clear: none;
float: none;
}

DIV.bm1 {width: 100%;
}

DIV.bm11 {padding: 0.5em 1em 1.5em 5em;
}

/* /div */
/* /div */
/* /div */

DIV.aboveTheFold {width: 100%;
clear: left;
}

DIV.ab1 {width: 100%;
}

DIV.ab11 {padding: 1em 2em 1em 1em;
}

/* /div */
/* /div */
/* /div */

DIV.footer {width: 100%;
clear: left;
}

DIV.fo1 {width: 100%;
}

DIV.fo13 {padding: 1%;
}

/* /div */
/* /div */
/* /div */

***** page variable specification file from LRP's Python "web framework" *********

pageTitle = "Latest Episode"
pageSYM = "welcome"
grid = "grid2"
security = "no"

***** "Part" content file ******

<h3>You can edit this panel </h3>
<p>
To edit this panel...
</p>












Vijay Kandy

unread,
Apr 6, 2009, 4:37:11 PM4/6/09
to Nitrogen Web Framework for Erlang
Hello Tom,

Nicely done. It's just like topmenu1 and topmenu2 in quickstart. I can
see how this is like a component.

I thought component was like a widget like in igoogle.com
(personalized google page) and I am glad its not that!

-Vijay

On Apr 4, 1:14 pm, Tom McNulty <tom.mcnu...@cetiforge.com> wrote:
> As requested, here is how I handled a login box. Nothing fancy, I hope  
> it lives up to the expectation ;)  As rusty mentioned, the magic is in  
> the delegate. LRP you wanted to keep HTML out of erl files. I can see  
> how this applies when you have large paragraphs of content that you  
> wish others to edit, but for the example below the HTML is actually  
> best suited inside erl files, so that it may be A) generated  
> dynamically B) abstracted away from the rest of the page content. All  
> styling is handled through external CSS.
>
> In general I tend to favor simple frameworks that allow me to create  
> what I need using basic constructs. As opposed to complex frameworks  
> which provide support for adding pre-built components simply. A long  
> time ago I tried a Java web framework called 'Tapestry'. The amount of  
> 'plumbing' to create generic components was in some cases more  
> extensive than the feature itself, it wasn't long before I just gave  
> up on it. And of course, the more specific your component is, the less  
> likely it's of use to others.
>
> Here's the final product. Nothing really interesting here.
>
> > On Sat, Apr 4, 2009 at 4:46 PM, mats <mats.wes...@gmail.com> wrote:
> > After reading #6 – I think the reddit team solved it by using a css  
> > compiler, that can handle variables, functions and nested styles. On  
> > slide 29 [1] they are talking about the C55 compiler. I don't say  
> > it's the right solution. Just FYI. (It's not out yet, but it will be  
> > open source.) It could be the most complicated solution to  
> > sandboxed  css. :)
>
> > I really like the atmosphere on this list, and it is exciting to see  
> > what is coming out next. Good work to the team!
>
> > /m
>
> > [1]http://blog.reddit.com/2009/04/ride-snake-reddits-pycon-09-keynote.html
>
> > On Sat, Apr 4, 2009 at 3:47 PM, Rusty Klophaus <rkloph...@gmail.com>  
> ...
>
> read more »

mats

unread,
Apr 7, 2009, 1:50:43 AM4/7/09
to nitro...@googlegroups.com
A well written blog post from Tobbe.
http://blog.tornkvist.org/blog.yaws?id=123971846244334

Rusty Klophaus

unread,
Apr 7, 2009, 7:43:07 AM4/7/09
to Nitrogen Web Framework for Erlang
Hi all,

I'm definitely open to anything that would make Nitrogen easier to
extend while keeping development clean and simple.

My main reason for going with a process dictionary is that passing
around a State variable is going to add extra cruft to the API.

In other words, the current approach is relatively clean:

wf:wire(element, Actions),
wf:update(element, NewHtml),
wf:state(flag, true),

Passing state around would lead to this:

State1 = wf:wire(State, element, Actions),
State2 = wf:update(State1, element NewHtml),
State3 = wf:state(State2, flag, true),

Conceptually, we already do this. State is stored in the process
dictionary under 'wf_state', so you can just imagine that this is what
we are doing:

put(wf_state, wf:wire(get(wf_state), element, Actions)),
put(wf_state, wf:update(get(wf_state), element NewHtml)),
put(wf_state, wf:state(get(wf_state), flag, true)),

Except all of the calls to get(wf_state) and put(wf_state, ...) occur
in the methods themselves.

Best,
Rusty

Rusty Klophaus

unread,
Apr 7, 2009, 7:46:30 AM4/7/09
to Nitrogen Web Framework for Erlang
P.S. - After re-reading my post, I realize that it seems out of
context in this thread. It responds to a point mentioned in Tobbe's
blog post about SeeThrough to which Mats linked. (http://
blog.tornkvist.org/blog.yaws?id=123971846244334)

etnt

unread,
Apr 7, 2009, 8:25:21 AM4/7/09
to Nitrogen Web Framework for Erlang


On Apr 7, 1:43 pm, Rusty Klophaus <rkloph...@gmail.com> wrote:
> Hi all,
>
> I'm definitely open to anything that would make Nitrogen easier to
> extend while keeping development clean and simple.
>
> My main reason for going with a process dictionary is that passing
> around a State variable is going to add extra cruft to the API.
>
> In other words, the current approach is relatively clean:
>
> wf:wire(element, Actions),
> wf:update(element, NewHtml),
> wf:state(flag, true),
>
> Passing state around would lead to this:
>
> State1 = wf:wire(State, element, Actions),
> State2 = wf:update(State1, element NewHtml),
> State3 = wf:state(State2, flag, true),

But doing it this way have very nice properties.
For example:

* It is easy to create Unit testcases, an effect of not relying on
side-effects.
* It is easy to debug, for example using a tool such as 'redbug' we
can easily
trace what data that enters a particular function (and leaves it),
and we can
do this in our production system.
* A side-effect free function is like a lego block, i.e. it can easily
be reused.
Also, its internals is of no concern for anybody else and can safely
be modified
as long as the Input/Output interface doesn't change.

The example above shows the use of: State1...State2... etc.
It is a case which seldom occurs, at least for me. As a thumb-of
rule,
I always try to make my function clauses short, constantly breaking
down the code into smaller pieces of functions. This way, I seldom
need to write code like the above example. If I need to perform
multiple updates of a datastructure, I often write code like this:

foldf([in(Key,Val2), in(Key2,Val),....], DB).

where foldf/2 and in/2 looks like:

foldf(Fs,Db) -> lists:foldf(fun(F, Acc) -> F(Acc) end, Db, Fs).
in(K,V) -> fun(Db) -> in(K,V,Db) end.

But I think that regardless of what style of programming you choose,
the benefits of side-effect free code that I've described, clearly
outweigh
the ugly looking code example. During my ~18 years of daily Erlang
programming, I've come to notice that whenever I end up with really
hard bugs, they often has to do with side-effects, either caused by
the use of Mnesia, by some message-passing gone a stray or by
timing issues. Confining your side-effects as much as possible
makes it possible to build the rest of you system in a rock-solid
lego fashion.

Sorry if I got somewhat off topic.
All the best and keep up the good work!
--Tobbe

ll...@paisite.com

unread,
Apr 7, 2009, 1:35:56 PM4/7/09
to nitro...@googlegroups.com

> A well written blog post from Tobbe.
> http://blog.tornkvist.org/blog.yaws?id=123971846244334

I'd venture that the truest thing one can say about templates is, "different horses for different courses."

Page-level, monolithic templates are fine for relatively simple pages.

But I argue that there is a conceptual mismatch between the way many web developers, particularly those on the programming side, see the web and the way many many sites are presented today, indeed, the way many page content developers and designers conceptualize a web page.

On the one hand, the conceptual unit is the "page." Makes sense, since the page is the basic unit of HTML.

But for well-trained designers the page is simply a frame for a "page grid." Squint your eyes and look at any magazine, newspaper, or even well-designed brochure, and you'll see a mathematical "grid" structure, where each panel in the grid is a container for content. True, many designers spread content over two or more panels, but the basic structure holds.

The grid system is a fundamental concept in many graphic design text books. Why? Because it provides a coherent way of organizing disparate elements of content.

Squint at many, if not most, well-designed, high-traffic websites and you'll see the grid system at work organizing the content. The grid system is like a well-organized closet with shelves and cubby holes -- everything has a place and everything is in its place, whereas a page-oriented design is more like one of my wife's kitchen drawers, everything tossed in a jumble with everything else (I should talk; my closets and drawers are even more disorganized).

Now take a look at amazon.com. I have no idea of how Amazon constructs its pages. Maybe as someone suggested it's a big hairy content management system. Doesn't matter to my basic argument.

Call up page source for the Amazon home page. Now squint your eyes and substitute variables for every substantive element; e.g. in your mind, turn the source into a template. Now imagine a programmer giving you a list of variable names for different dynamic content elements and working through the template to match content item with place-holder in your big, long, hairy template file.

I'm sure no one does it quite this way, but you get the idea.

Now take another look at Amazon's home page. Squint your eyes and you'll see a simple three-column grid, or "make-up" as a designer would say; e.g. left and right side bars surrounding a main content panel.

Look more closely at the top of the grid and you'll see three content elements (personalization line, personal menu, and search bar) that span the content column and right side bar. They're still consistent with the basic grid, but they add visual diversity and interest while keeping content well organized.

Further note that the basic columns contain simple lists of content elements stacked one atop another.

Now, look at the variety of content elements that fill the panels in the grid and think about the code, HTML formating, and CSS styling tags needed to create each element. You'll note that some elements are straight text, some are text and graphics, some made up of hyper links, some form elements, some buttons, and some report data drawn up from a database.

When I talk about "Parts," this is essentially what I'm talking about. Content elements can be abstracted into a set of "Parts," distinguished by underlying logic.

Now imagine a page construction process that goes like this:

1) Programmers provide an inventory of Parts, single-function black boxes of code that can be configured with content and styling to generate content elements.

2) Select the Parts you need to convey the information you want. Enter content for each.

3) Design (or select from an inventory) a page grid, essentially a list of DIVs (see my earlier post for example).

4) Develop (or select from inventory) CSS file(s) for your page

5) Plug parts into the page grid

6) Tweak styles in each part if necessary to maintain stylistic consistency with page.

A system like this:

1) Is conceptually consistent with the way content developers and trained designers think

2) Does not necessarily require the page designer to adopt any additional tools beyond HTML and CSS.

3) Breaks down a potentially confusing task into a set of relatively simple tasks.

4) Content and styling can be configured with a simple text editor on the one hand, or sophisticated GUI tools on the other. Indeed, GUI tools could be an additional layer on top of the simpler system.

If the base system were open-source, then specialized parts and GUI systems could add value to meet specialized requirements or support a variety of business models.
E.g., Parts could be open-source or proprietary; offering the best of both worlds.

5) Encourages substantial code reuse.

6) Pushes code complexity down into the Parts. With careful factoring, code complexity may never even be an issue but for the rarest and most algorithmically challenging Parts.


7) Offers great flexibility. Change the page grid and/or the high-level CSS file and you change the basic look of the page. Reuse content elements across pages. Change a content element with little to no interaction with other content elements.

8) If we fore go fancy GUI content editing and styling tools, then this system can be fairly simple to implement; puts no added burden on the one-man-band web site developer.

9) In my experience with systems that conceptually approach this model I've seen substantial acceleration of productivity.

So, I argue, divide and conquer!

All the best,

Lloyd


etnt

unread,
Apr 7, 2009, 2:16:12 PM4/7/09
to Nitrogen Web Framework for Erlang
Excellent put! Now we're really getting somewhere :-)

On Apr 7, 7:35 pm, ll...@paisite.com wrote:
> > A well written blog post from Tobbe.
> >http://blog.tornkvist.org/blog.yaws?id=123971846244334
>
> I'd venture that the truest thing one can say about templates is, "different horses for different courses."
>
> Page-level, monolithic templates are fine for relatively simple pages.

Indeed and just for reference: Our Web-GUI has a very simple structure
but there are many 'pages'. I just counted and we are sitting on top
of
65000 lines of Erlang+ehtml manure.

>
> But I argue that there is a conceptual mismatch between the way many web developers, particularly those on the programming side, see the web and the way many many sites are presented today, indeed, the way many page content developers and designers conceptualize a web page.
>
> On the one hand, the conceptual unit is the "page." Makes sense, since the page is the basic unit of HTML.
>
> But for well-trained designers the page is simply a frame for a "page grid." Squint your eyes and look at any magazine, newspaper, or even well-designed brochure, and you'll see a mathematical "grid" structure, where each panel in the grid is a container for content. True, many designers spread content over two or more panels, but the basic structure holds.
>
> The grid system is a fundamental concept in many graphic design text books. Why? Because it provides a coherent way of organizing disparate elements of content.
>

Interesting. I have recently started to play around with grid based
approaches
using the Blueprint-CSS ( https://github.com/joshuaclayton/blueprint-css/tree
)
and I like it a lot.

> Squint at many, if not most, well-designed, high-traffic websites and you'll see the grid system at work organizing the content. The grid system is like a well-organized closet with shelves and cubby holes -- everything has a place and everything is in its place, whereas a page-oriented design is more like one of my wife's kitchen drawers, everything tossed in a jumble with everything else (I should talk; my closets and drawers are even more disorganized).
>
> Now take a look at amazon.com. I have no idea of how Amazon constructs its pages. Maybe as someone suggested it's a big hairy content management system. Doesn't matter to my basic argument.
>
> Call up page source for the Amazon home page. Now squint your eyes and substitute variables for every substantive element; e.g. in your mind, turn the source into a template. Now imagine a programmer giving you a list of variable names for different dynamic content elements and working through the template to match content item with place-holder in your big, long, hairy template file.
>
> I'm sure no one does it quite this way, but you get the idea.
>
> Now take another look at Amazon's home page. Squint your eyes and you'll see a simple three-column grid, or "make-up" as a designer would say; e.g. left and right side bars surrounding a main content panel.
>
> Look more closely at the top of the grid and you'll see three content elements (personalization line, personal menu, and search bar) that span the content column and right side bar. They're still consistent with the basic grid, but they add visual diversity and interest while keeping content well organized.
>
> Further note that the basic columns contain simple lists of content elements stacked one atop another.
>
> Now, look at the variety of content elements that fill the panels in the grid and think about the code, HTML formating, and CSS styling tags needed to create each element. You'll note that some elements are straight text, some are text and graphics, some made up of hyper links, some form elements, some buttons, and some report data drawn up from a database.
>
> When I talk about "Parts," this is essentially what I'm talking about. Content elements can be abstracted into a set of "Parts," distinguished by underlying logic.
>
> Now imagine a page construction process that goes like this:
>
> 1) Programmers provide an inventory of Parts, single-function black boxes of code that can be configured with content and styling to generate content elements.
>

I guess that this still allows for using template-snippets or ehtml
or whatever, as basis for the
generated HTML ? I wonder how these parts should be described to help
the 'designer' to choose
the parts he needs? I'm thinking that perhaps could a template-snippet
be both the base from
where the HTML is generated as well as the documentation in a form
that the designer will understand?
If you are using some kind of 'ehtml' then that need to be documented
in some other form, or?

> 2) Select the Parts you need to convey the information you want. Enter content for each.
>
> 3) Design (or select from an inventory) a page grid, essentially a list of DIVs (see my earlier post for example).
>
> 4) Develop (or select from inventory) CSS file(s) for your page
>
> 5) Plug parts into the page grid
>

Interesting, do there exist any examples of systems built up like
this?
Or are we perhaps talking about CMS like systems?

> 6) Tweak styles in each part if necessary to maintain stylistic consistency with page.
>
> A system like this:
>
> 1) Is conceptually consistent with the way content developers and trained designers think
>
> 2) Does not necessarily require the page designer to adopt any additional tools beyond HTML and CSS.
>
> 3) Breaks down a potentially confusing task into a set of relatively simple tasks.
>
> 4) Content and styling can be configured with a simple text editor on the one hand, or sophisticated GUI tools on the other. Indeed, GUI tools could be an additional layer on top of the simpler system.
>
> If the base system were open-source, then specialized parts and GUI systems could add value to meet specialized requirements or support a variety of business models.
> E.g., Parts could be open-source or proprietary; offering the best of both worlds.
>
> 5) Encourages substantial code reuse.
>
> 6) Pushes code complexity down into the Parts. With careful factoring, code complexity may never even be an issue but for the rarest and most algorithmically challenging Parts.
>
> 7) Offers great flexibility. Change the page grid and/or the high-level CSS file and you change the basic look of the page. Reuse content elements across pages. Change a content element with little to no interaction with other content elements.
>
> 8) If we fore go fancy GUI content editing and styling tools, then this system can be fairly simple to implement; puts no added burden on the one-man-band web site developer.
>
> 9) In my experience with systems that conceptually approach this model I've seen substantial acceleration of productivity.
>
> So, I argue, divide and conquer!
>
> All the best,

Thanx, you really provided some food for thoughts here!
Cheers, Tobbe

>
> Lloyd

Vijay Kandy

unread,
Apr 7, 2009, 3:25:32 PM4/7/09
to Nitrogen Web Framework for Erlang
Lloyd wrote:
> When I talk about "Parts," this is essentially what I'm talking about. Content elements can be abstracted into a set of "Parts," distinguished by underlying logic.

Tobbe wrote:
> Interesting, do there exist any examples of systems built up like
> this?
> Or are we perhaps talking about CMS like systems?

Now I think I understand what Lloyd's concept of "Parts". In Java
world, (I've been working with C/Java for 8+ years) there's a project
called Tiles (http://struts.apache.org/1.x/struts-tiles/examples.html)
which is based on the similar concept. You define a layout and include
pages in the layout definition like so:

<definition name="templateDefinition" path="/layout.jsp">
<put name="title" value="This is the title." />
<put name="header" value="header.jsp" />
<put name="body" value="body.jsp" />
</definition>

Think of JSPs as .ERL files. We could define a layout composed of
several ERL files (tiles), and when it is rendered, a user sees it as
1 single HTML file in the browser.

It's not CMS. It's a clever technique of creating pages by
accumulating contents from several smaller, content specific pages.
This has several advantages:

1. We don't write giant monolithic pages.
2. Logic can be distributed in multiple pages.
3. If something goes wrong with a page, the whole page doesn't get
screwed - just the single tile that has problem will show up like a
blank page.

Is this close to what your "Parts" idea Lloyd?

-Vijay

etnt

unread,
Apr 7, 2009, 3:42:41 PM4/7/09
to Nitrogen Web Framework for Erlang
Comparing this with Blueprint-CSS, where you specify a grid using
a number of columns. So lets say you have a 24 colum grid.
You could then specify a layout like this:

[{"span-24 last", {mymod,top_bar,[]}},
{"span-8", {mymod,github_badge,[]}},
{"span-3", "&nbsp;"},
{"span-8", {mymod,more_stuff,[]}},
{"span-5 last", ""},
{"span-12 pull-4 myprepend-top-4", {mymod,flickr_gallery,[]}},
{"span-12 last", ""}].

And this is exactly the layout of http://www.tornkvist.org/ :-)

--Tobbe

ll...@paisite.com

unread,
Apr 7, 2009, 8:01:19 PM4/7/09
to nitro...@googlegroups.com
Hi Tobbe,


> Interesting. I have recently started to play around with grid based approaches
> using the Blueprint-CSS ( https://github.com/joshuaclayton/blueprint-css/tree
)
> and I like it a lot.

Blueprrint-CSS does indeed look interesting. And looks like the people behind know what they're doing from hard experience.

I've only taken a quick look-see, but look forward to spending some serious time looking into it.

> I guess that this still allows for using template-snippets or ehtml
> or whatever, as basis for the generated HTML ?

I would think so. From my experience web content comes about in four ways: entered and edited as page content by content providers (or editorial surrogates); delivered over the network from some remote node; composed as reports from db-based data; or synthesized through some algorithmic method.

Obviously, how content comes about is the essential business of the programmer. But from the point of view of the content provider and page designer (I think of these as roles, not necessarily as separate people), the technical processes behind how content is taken from raw input to display is of little concern, as long it's easy to make happen and it works. Thus, my argument for named, encapsulated, black boxes of code.

> I wonder how these parts should be described to help the 'designer' to choose
> the parts he needs? I'm thinking that perhaps could a template-snippet
> be both the base from where the HTML is generated as well as the documentation
> in a form that the designer will understand?

Those are excellent questions; worth considerable discussion and prototyping.

As to naming, names should clearly reflect functionality as understood by the page developer; e.g. "login1," "textPanel1," "imageWithCaption1," "registrationTool1," etc.

Note that I index the names to allow variations on the same function.

An important convention in building Parts, I believe, would be to provide a short, descriptive paragraph that describes the function of the Part."

In a perfect world there'd be at least one open-source archive of Parts. Developers may well also maintain their own proprietary archives.

> If you are using some kind of 'ehtml' then that need to be documented in some other
> form, or?

I have no opinion yet. I've done much of this, crudely, in Cold Fusion and Python. But I'm still working toward how to Think Erlang.

> Interesting, do there exist any examples of systems built up like
> this?

As noted in an earlier post, I spent some 12 years building and rebuilding a large, full-featured, web-based conference marketing and management system. Written in Cold Fusion with an SQL db back-end, it supported both public pages for marketing the conference; form pages for on-line registration; on-site conference delegate tools for maintaining personal schedules, arranging meetings with experts, etc., etc., etc.; and extensive back-office administrative support. Sort of soup to nuts.

As our thinking evolved, it converged toward the architectural ideas I've been advocating. Each step closer gave us enhanced productivity.

I also built a simple prototype in Python for my manga site, ayatakeo.com.

> Or are we perhaps talking about CMS like systems?

I'm thinking a base system where everything can be done through a text editor. This should be quite adequate for the one-man-band site developer or, even, the tech-savvy web development house.

As I suggested earlier, fancy CMS functionality, GUI tools, etc., can be built on top of the base system. I can imagine half a dozen systems, all designed for different work environments and to meet different requirements, all built on top of the base system.

As stressed earlier, keep it simple; walk before you run.

> Thanx, you really provided some food for thoughts here!

Thank you, Tobbe. I'm pleased that these ideas are sparking interest among serious folks. Hope to see you at Erlang University.

All the best,

Lloyd


ll...@paisite.com

unread,
Apr 7, 2009, 8:05:23 PM4/7/09
to nitro...@googlegroups.com
Hi Vijay,

> Is this close to what your "Parts" idea Lloyd?

You're converging on it.

Take a look at my April 6, 2:12 pm post to see how I configure pages in my Python tinker-toy prototype. You can see the page at ayatakeo.com.

Many thanks for your interest.

Lloyd

ll...@paisite.com

unread,
Apr 7, 2009, 8:11:43 PM4/7/09
to nitro...@googlegroups.com
Hello again,


> And this is exactly the layout of http://www.tornkvist.org/ :-)

Blueprint-CSS specification looks fairly straight-forward. I need to look deeper.

Your home page is beautiful. I did get an error when I clicked on The Priority List.

You're doing some exciting work, Tobbe!

Best,

Lloyd

Vijay Kandy

unread,
Apr 7, 2009, 8:56:02 PM4/7/09
to Nitrogen Web Framework for Erlang
On Apr 7, 1:42 pm, etnt <torbjorn.tornkv...@gmail.com> wrote:
> Comparing this with Blueprint-CSS, where you specify a grid using
> a number of columns. So lets say you have a 24 colum grid.
> You could then specify a layout like this:

Tobbe,

I'll agree with you .... to a certain extent. You can use CSS to
manage components. But that would be simplifying the problem. If the
goal is to write a simple web application (simple meaning mostly
CRUD), invoking modules as in your example, is perfectly fine.

But when you set out to implement a site like Amazon or anything more
that CRUD operations, you would want to implement it with MVC pattern,
which I am sure you are aware of. Basically, you separate "business
logic" from "presentation logic" and use a controller to dispatch
requests and render views. That's when layouts can be helpful.
Controller can gather content and render Views.

Personally, I liked Nitrogen because it doesn't implement MVC. Its
simple. Yes, you mix business logic and presentation logic in 1 file
but that's not a big deal in my app.

-Vijay

Vijay Kandy

unread,
Apr 7, 2009, 9:05:38 PM4/7/09
to Nitrogen Web Framework for Erlang
> Take a look at my April 6, 2:12 pm post to see how I configure pages in my Python tinker-toy prototype. You can see the page at ayatakeo.com.
>
You are wiring components with CSS? I think that's what Tobbe showed
in his example ...

Steve Davis

unread,
Apr 8, 2009, 8:14:01 AM4/8/09
to Nitrogen Web Framework for Erlang
Hi Rusty,

The following two frameworks from Java may (or may not) provide some
inspiration either now or later with respect to this thread on
"templating". Below are frameworks that I believe represent the "best
of the best" of the Java web frameworks (i.e.: more interesting and
developer friendly than the most popular ones, namely Struts/Shale and
Spring).

Apache Tapestry - a simple to use, page-oriented framework with good
separation: http://tapestry.apache.org/
JBoss SEAM - a more complex/capable full-application framework:
http://seamframework.org/

Regards,
Steve

Vijay Kandy

unread,
Apr 8, 2009, 1:32:13 PM4/8/09
to Nitrogen Web Framework for Erlang
> The following two frameworks from Java may (or may not) provide some
> inspiration either now or later with respect to this thread on
> "templating". Below are frameworks that I believe represent the "best
> of the best" of the Java web frameworks (i.e.: more interesting and
> developer friendly than the most popular ones, namely Struts/Shale and
> Spring).
>
> Apache Tapestry - a simple to use, page-oriented framework with good
> separation:http://tapestry.apache.org/
> JBoss SEAM - a more complex/capable full-application framework:http://seamframework.org/

Best of the best? All these frameworks are at the other end of the
spectrum.

Remember, Java frameworks are based on OO concepts. These frameworks
were created in the first place to solve some big problems. Object
creation and thread creation is expensive, hence we have object pools
and thread pools, connection pools. There are multiple layers, pools
and unnecessary complexity. They try to relieve some problems in the
Java world but I don't think they are relevant in Erlang. There are a
few things I miss in Erlang like JMS but that's another story. I
should also mention that to compensate for what Java doesn't provide
in terms of OO, people are leaning towards Dependency Injection - you
can see the heavy use of annotations for traits like behavior.

The problems in the Java world are not the same or even similar in
Erlang world. We use Concurrency Oriented Programming. So, I don't see
why we should model Erlang frameworks after Java frameworks.
Simplicity is what attracted me to Erlang and Nitrogen. You could
compare Nitrogen with Lift (http://demo.liftweb.net/index). I looked
at Lift briefly but I still like Nitrogen.

ll...@paisite.com

unread,
Apr 9, 2009, 2:24:16 AM4/9/09
to nitro...@googlegroups.com
Hi Vijay,

> You are wiring components with CSS?

Not sure I'd use the word wiring, but using a CSS file to create the page grid, then interpreting it within body to create the DIVs and call in the components.

> I think that's what Tobbe showed in his example ...

Must have missed this. Will take another look.

Best,

Lloyd

ll...@paisite.com

unread,
Apr 9, 2009, 2:54:14 AM4/9/09
to nitro...@googlegroups.com
Hi Steve,

> Apache Tapestry - a simple to use, page-oriented framework with good
> separation: http://tapestry.apache.org/
> JBoss SEAM - a more complex/capable full-application framework:
> http://seamframework.org/

Just took a very quick glance at Tapestry and SEAM. From the little I gather they look rather interesting.

I don't know Java, but people tell me that my thinking about Parts is similar to the Java servlet concept. Do you have a sense of the strengths/limitations of servlets?

Two basic concepts seem to be bubbling under the surface of our thread:

1) Encapsulate code into single-function Parts/components that can be mix, matched, and reused in web pages.

2) Use the existing presentation technologies of HTML, CSS, and Javascript to control where, when, and how Parts/components are called up to deliver content.

Four tricky issues seem to lurk in the dark doorways:

1) How to manage state and state variables
2) How to manage interaction across Parts/components
3) How to deal with persistence requirements of Parts/components
4) How to do this simply and elegantly in Erlang

And a big question:

Is this asking too much of Nitrogen?

Not sure I've got that quite right. Welcome refinement.

If we can find a clear, comprehensive way to frame the issues/questions, then the answers shouldn't be too far behind.

All the best,

Lloyd


Joe Armstrong

unread,
Apr 9, 2009, 4:10:37 PM4/9/09
to nitro...@googlegroups.com
Some thoughts about web pages .... and proposal for a system of
web pages that is composable ...

--

A while back I began thinking how to make web pages behave more like
regular functions and came up with a few ideas.

The problem with web pages is that they can't call each other and that
each HTML file needs a new file. Why can't I stuff all web pages into
one file. If I have (for example) an abstraction "rounded corner
boxes" why can't I define it *once* and reuse it several times (well I
can but I have to drop into javascript)

Also "what is a web page". A first try at answering this might be "a
function that returns HTML" but this is not good enough. Let's try
again "a function which returns HTML *and HEADERS" - better but not
perfect.

Try again: "A pure function of an environment which contains headers, etc,
and returns HTML and a new environment"

(Note the environment in addition to headers, can contain, for example
the state of a data base etc - the environment contains the *state* of
the session)

At the moment one web page = one HTML file. But this doesn't have to
be so.

In what follows I'll outline a syntax and semantics of a system that
provides composable, side-effect free web pages. I implemented this a
few years ago but haven't done anything with it - it might be nice to
relaunch this in a nitrogen context.

Idea 1)

Stuff many web pages into one file (call these ".web" files)

For example: the file myproj.web

@webpage index(Args)
<title>index</title>
<h1>I am the index</h1>
<p>Go to <a href="page1.html?a=1&b=2">page1</a>
@webpage page1(Args)
<h1>Page 1</h1>
@webpage page2(Args)
...
-- end

This defines three web pages in the same file. When I reference
http://site/myproj/index.html I call the Erlang function
myproj:index(Args) - Args is a data structure containing the HTML
Headers and command arguments

Idea 2)

Web pages can call erlang.

Example:

@webpage index(Args)
<h1>hello</h1>
<? A1 = foo(Args), A2= bar(A1), baz(A2) ?>
<p>
<? z(A2), ... ?>
@webpage ...

The stuff inside <? ... ?> is regular Erlang.
The bindings A1, ... are carried through the function precisely as in the
body of an erlang function.

Semantics: <? E1, E2, ,.. En?> is evaluated. The value of En is pasted
into the HTML and replaces <? ... ?>

Idea 3)

Erlang can call a web page. More tricky this one.

A web page is a function of type Name x Args -> Headers x HTML.
(almost, I'll pretend this is true for now, later I'll make a better
version)

This needs an example:

@webpage index(Args)
<h1>hello</h1>
<? rounded_corner_box("Title", "body") ?>
@webpage mybox(Args)
<div class="..." id=<?newid()?>
<?getArg(title, Args)?>
...
@erl
rounded_corner_box(Title, Body) ->
{Headers, HTML} = mybox([{title, T}, {body,B}]),
HTML.

-- end

Idea 4) Webpages have side effects - update databases etc.

This is actually a generalisation of the the idea of "headers"

Wait a bit to see how this is compiled/translated

---- How is this compiled/translated?

A .web file is *really* just an Erlang module

example: foo.web

@webpage index(Args)
<h1> ....
@webpage page1(Args)
...
@erl
foo(A, B) ->
...

Is compiled into a module foo.erl which exports index/1, page1/1 foo/2
etc.

How is this translated?

Easy - here's an example

foo.web
@webpage index(Args)
<h1>hello</h1>
<? A1=foo(1,2), B=baz(A1), "hello" ?>
<p>bar
@webpage page1(Args)
...
@erl
foo(A, B) ->
..

Is translated into

-module(foo).
-export([index/1]).

index(Args) ->
R1 = <<"<he>hello</h1>">>,
A1 = foo(1,1),
B = baz(A1),
R2 = <<"hello">>,
R3 = <<"<p>bar">>,
{[], [R1,R2,R3]}.

page1(Args) ->
....

Easy :-) (There are better translations, but this way is easy to grok)
R1, R2, ..are new unused variables containing the "result"

Haven't we forgotten anything? - Yes side effects (Headers etc.)
We add a single pseudo variable which *must* be assigned in
a <? ... ?> black, called OUT. The translation is like this:

@webpage foo(Args)
<h1>hello</h1>
<? OUT=[lib:add_header("Context-Type/blaaa")], "" ?>
<p>a

Translates into

foo(Args) ->
R1 = <<"<h1>hello</h1>">>,
Out = [lib:add_header("Context-Type/blaaa")],
R2 = <<""">>,
R3 = <<"<p>a">>,
{Out, [R1,R2,R3]}
....


In some ways this is like PHP, only the sematics is "done right" with
no unecessary side effect (which will make things nicely composable).

/Joe Armstrong

ll...@paisite.com

unread,
Apr 9, 2009, 8:15:36 PM4/9/09
to nitro...@googlegroups.com
Hi Joe,

Delighted that you've given this issue thought.

By composable, do you mean web pages that are build on reusable Erlang functions?

Are these functions what you mean by "rounded corner black boxes?"

If so, I'm with you on that. And keeping these functions side-effect free makes good sense based on arguments you've presented elsewhere.

As to definition of a web page, your third definition, "A pure function of an environment which contains headers, etc, and returns HTML and a new environment," rings the most bells for me.

But I have trouble with trying to put the whole web site into one file. Wouldn't it be great if we could. But as I've argued elsewhere in this thread we often have different "roles" involved in the creation of the site -- the programming role, the page content role, and the page design/styling role. Except for those renaissance type one-man-band site developers, each of these role players sees the work of the others as so much noise.

I spent years developing in Cold Fusion, a proprietary predecessor of PHP which uses the same logic embedded in presentation style of development. Believe me, with more complex pages, particularly in the days prior to CSS, it was a bitch.

This, I think is the reason that many frameworks try to separate data from logic and logic from presentation. Yet, you're right, having all those pesky files to dig through can be a pain.

Now, embedding simple id-type tags that reference reusable functions, each with all the functionality that goes within a DIV does make sense to me and is what I've been advocating.

How best to make it happen, however... I just don't know enough Erlang yet to proceed.

With good minds like yours hammering on it, however, I can't help but see a truly stupendous solution somewhere not that far down the line.

All the best,

Lloyd



Joe Armstrong

unread,
Apr 10, 2009, 11:13:17 AM4/10/09
to nitro...@googlegroups.com
On Fri, Apr 10, 2009 at 2:15 AM, <ll...@paisite.com> wrote:
>
> Hi Joe,
>
> Delighted that you've given this issue thought.
>
> By composable, do you mean web pages that are build on reusable Erlang functions?

I mean a web page is a represented as a pure function with no side effects.

pageName(InArgs) -> {OutArgs, HTML}

If you call it a zillion times with the same InArgs it will return the same
return value. This made testing and understanding what these functions do
a lot easier than hiding side effect inside the functions.

InArgs is some record (to be defined) containing the URI args, the "state of the
session" is the user authenticated etc, possible database values.

OutArgs will contain headers (to be sent to the web browser), the new state
of the database etc.

We can also write functions returning only HTML and call them as I suggested


>
> Are these functions what you mean by "rounded corner black boxes?"
>

Could be

> If so, I'm with you on that. And keeping these functions side-effect free makes good sense based on arguments you've presented elsewhere.
>
> As to definition of a web page, your third definition, "A pure function of an environment which contains headers, etc, and returns HTML and a new environment," rings the most bells for me.
>
> But I have trouble with trying to put the whole web site into one file. Wouldn't it be great if we could. But as I've argued elsewhere in this thread we often have different "roles" involved in the creation of the site -- the programming role, the page content role, and the page design/styling role. Except for those renaissance type one-man-band site developers, each of these role players sees the work of the others as so much noise.

Yes - it seems to me that shipping an application an "open" file structure
breaks a basic principle of encapsulation. In my perfect world there would be
a single directory "/apps". To install an application I'd drop a
single file into "/apps" - that's it. To uninstall I delete the file -
after uninstalling the system
shoud be in the same state as it was prior to installing (with the exception of
a log file, that said that I installed and unistalled, etc., possiblly
some settings
that I might want to use if I reinstall later)

The point is a user shoudl not see the internal structure of an appliction -
a *developer* should see the necessary parts of the structure, necessary for
the the construction. File systems (by exposing everything) break basic
principles of encapsulation (an object is a black box with a defined interface).

Thus I do not like scaffolding generators - make a command and suddenly
my disk is full of mysterious files, whoes contents is a mystery.

Better would be that "make_app" creates a single file whies content is
revealed through a defined interface (like a database, in fact)


>
> I spent years developing in Cold Fusion, a proprietary predecessor of PHP which uses the same logic embedded in presentation style of development. Believe me, with more complex pages, particularly in the days prior to CSS, it was a bitch.
>
> This, I think is the reason that many frameworks try to separate data from logic and logic from presentation. Yet, you're right, having all those pesky files to dig through can be a pain.

I have no real preference here - since I see no differences between
logic and presentation. presentation *is* (constant) logic

Imagine a page like like this

<h1>hello</h1>
<? aFunctionWhichReturnsHTML(...) ?>
<p>hello

I see this as a list of functions:

id("<h1>hello</h1>")
aFunctionWhichWhenReturnsHTML(...)
id("<p>hello")

The id function just returns it's argument (id(X) -> X)

Web pages with arguments are just lambda abractions

ie

<p>hello ${name} you are ${age} years old

*is* a lambda abstraction

fun(Name, Age) ->
["<p>hello", Name, "you are", Age, "years old"]
end

Viewed this way there is no separation of logic and presentation - everything
is logic :-)

Another way of thinking might be to view a web page as a process
containing named holes.

To fill a hole you send the page a message

Page ! {fillHole, a, "<p>hello"}

This fills the hole named "a"

To read a hole you send the web page a message

Page ! {read, "a"}

It sends back the content.

JoePage would be a permanent process to which I could send messages
(irrepective of whether the page is displayed or not)

JoePage ! {fillehole, "a", "hello"}

would cause a permanent change to joepage (until the next message) - this
way any database involved is abstracted away. We only have "persistent pages"
and therefore there is no need of a database (we might *implement* this using
a database - but knowing *how* this is implemented breaks (yet
another) abstraction - we shouldn't need to know) we should only need
to know
"there are pages with names" and "we can change them by sending them
messages according to some defined protocol" - how there are
represented
and stored is irrelevant. (They might in fact be represented in many
different ways)

What we are talking about is the purest form of objects - where
objects are totally isolated and can only be influenced by message
passing.

In this case the web page *is* an object - the only way we can change
it is by sending it a message.

Must think more about this

... perhapse we just need
a cloan operation. There is a generic web page (say foo) from which we
can cloan "joe's version of foo)

Foo looks like this

<h1>hello <span id="name"></span></h1>
....

They I can create cloan and sent it a message

JoesFoo = cloan("foo"),
JoesFoo ! {fillregion, "name", "joe"}

This persistent - JoesFoo lives in a store it can be pulled out
of the store and displayed

I need to think about this more ... this is just stream of consciousness ...

Cheers

/Joe
]

ll...@paisite.com

unread,
Apr 10, 2009, 12:44:59 PM4/10/09
to nitro...@googlegroups.com
Hi Joe,

> I mean a web page is a represented as a pure function with no side effects.
> pageName(InArgs) -> {OutArgs, HTML}

Got it. Thanks.

> Yes - it seems to me that shipping an application an "open" file structure
breaks a basic principle of encapsulation. In my perfect world there would be
a single directory "/apps". To install an application I'd drop a
single file into "/apps" - that's it. To uninstall I delete the file -
after uninstalling the system
shoud be in the same state as it was prior to installing (with the exception of
a log file, that said that I installed and unistalled, etc., possiblly
some settings
that I might want to use if I reinstall later)

It might be valuable here to clarify what we mean by "application."

Is it:

- the web site as a whole?
- a page in the web site?
- a unit of functionality in a page?

I have been arguing for encapsulation of distinct units of functionality.

By unit of functionality I mean a "rounded corner black box," to use your term, that delivers a unit of meaningful information to the ultimate consumer. It might be as simple as a block of text or a site navigation menu. It might be as complex as a sequence of conference registration panels. But in principle, and probably in general, a single web page would be composed of MORE THAN ONE of these "rounded corner black boxes." And the purposes and functionality of each of these units would in all likelihood be different one from another, as would the technical underpinnings.

Given this, I completely agree that our "unit of functionality" should be "composable," e.g. completely encapsulated. But it may be more expedient to encapsulate it within a single directory than within a single file.

Why? Presumably we'd want to reuse our nifty little black box, but in such case we'd want to alter content (text and images) as well as styling.

In contrast, I see major challenges in trying to encompass an entire site or, indeed, an entire page within a single "rounded corner black box." Among other things, we would most definitely lose the virtues of reusability. Why would you want my page in your site?

But given all that, I totally agree that encapsulation at some level would improve ease and productivity of web site construction immeasurably.


> The point is a user shoudl not see the internal structure of an appliction -
a *developer* should see the necessary parts of the structure, necessary for
the the construction. File systems (by exposing everything) break basic
principles of encapsulation (an object is a black box with a defined interface).

With you 100%.

> Better would be that "make_app" creates a single file whies content is
> revealed through a defined interface (like a database, in fact)

Or, as argued above, a single directory.

> I have no real preference here - since I see no differences between
> logic and presentation. presentation *is* (constant) logic

> Imagine a page like like this

> <h1>hello</h1>
> <? aFunctionWhichReturnsHTML(...) ?>
> <p>hello

I would imagine it more as:

<? Function1WhichReturnsHTML(...) ?>
<? Function2WhichReturnsHTML(...) ?>
<? Function3WhichReturnsHTML(...) ?>

No more, no less.

> I see this as a list of functions:

> id("<h1>hello</h1>")
> aFunctionWhichWhenReturnsHTML(...)
> id("<p>hello")

> The id function just returns it's argument (id(X) -> X)

Are we talking about the same thing here? If reflect on the fact that most textual content within typical web pages is more of the form:

<h4>headline</h4>
<p>paragraph of text</p>
<p>another paragraph</p>
<h3>subhead</h3>
<p>paragraph of text</p>

...then I believe we are.

> Web pages with arguments are just lambda abractions

> ie

> <p>hello ${name} you are ${age} years old

> *is* a lambda abstraction

> fun(Name, Age) ->
> ["<p>hello", Name, "you are", Age, "years old"]
> end

OK. But I would see this embedded within our "unit of functionality."

> Viewed this way there is no separation of logic and presentation - everything
is logic :-)

OK

> Another way of thinking might be to view a web page as a process
> containing named holes.

If we substitute "Part," a name that I suggested earlier for our "units of functionality" for "web page" in your above sentence, then everything you argue below makes sense with the added benefit that it enables one "Part" to pass messages to another part within a given page.

All the best,

Lloyd

Russell Klophaus

unread,
Apr 10, 2009, 1:14:32 PM4/10/09
to nitro...@googlegroups.com
Hi Lloyd,

Can you (or anyone) help me understand what in your "parts" vision is not fulfilled by custom Nitrogen element? (Functionality which already exists in Nitrogen.)

A custom Nitrogen element lets you add to the basic elements provided (such as #textbox, #table, #panel, etc.) with elements of your own design (such as #loginform, #rssfeed, #feedbackform, etc.) Tom McNulty already posted an example of this.

Am I missing something? I feel like we keep talking about some magical, encapsulated, mini-application as if it is some unreachable vision of the future, when in reality it already exists, and is what Nitrogen is based on. Maybe the problem is just a lack of documentation?

Best,
Rusty

ll...@paisite.com

unread,
Apr 10, 2009, 5:49:43 PM4/10/09
to nitro...@googlegroups.com
Hi Rusty,

> Can you (or anyone) help me understand what in your "parts" vision is not
> fulfilled by custom Nitrogen element? (Functionality which already exists in
> Nitrogen.)

> A custom Nitrogen element lets you add to the basic elements provided (such
> as #textbox, #table, #panel, etc.) with elements of your own design (such as
> #loginform, #rssfeed, #feedbackform, etc.) Tom McNulty already posted an
> example of this.

> Am I missing something?

More likely you're seeing my limited understanding of Nitrogen. I don't understand yet how to build out from it, so merely expressing what I'd like to do with it.

My apologies if I've confused the issue or wasted anyone's time.

> I feel like we keep talking about some magical,
> encapsulated, mini-application as if it is some unreachable vision of the
> future, when in reality it already exists, and is what Nitrogen is based on.

Clearly I need to develop a deeper understanding of Nitrogen.

> Maybe the problem is just a lack of documentation?

For me it definitely is an issue. Others seem to catch on... through analysis or intuition I can't say. But I need to follow a few clear examples, experience a bit of success, then experiment to see how I can extend and build on those nuggets of working code.

For me it also helps to have a conceptual overview of the system and how the key subsystems work together. I suppose I should be able to dig that out of source. But I'm just now learning how to do that.

I haven't looked at Nitrogen for several weeks now (last time I did notice and admire your attractive new web design), so maybe there's more there now than I'm aware of.

If I ask naive questions, please bear with me. If I'm uninformed or confused, chances are a few others are too.

Once again, many thanks for your great work with Nitrogen.

Lloyd R. Prentice


Joe Armstrong

unread,
Apr 11, 2009, 2:46:32 PM4/11/09
to nitro...@googlegroups.com
On Fri, Apr 10, 2009 at 6:44 PM, <ll...@paisite.com> wrote:
>
> Hi Joe,
>
>> I mean a web page is a represented as a pure function with no side effects.
>>      pageName(InArgs) -> {OutArgs, HTML}
>
> Got it. Thanks.
>
>> Yes - it seems to me that shipping an application an "open" file structure
> breaks a basic principle of encapsulation. In my perfect world there would be
> a single directory "/apps". To install an application I'd drop a
> single file into "/apps" - that's it. To uninstall I delete the file -
> after uninstalling the system
> shoud be in the same state as it was prior to installing (with the exception of
> a log file, that said that I installed and unistalled, etc., possiblly
> some settings
> that I might want to use if I reinstall later)
>
> It might be valuable here to clarify what we mean by "application."
>
> Is it:
>
> - the web site as a whole?

Yes

> - a page in the web site?

No

> - a unit of functionality in a page?

No
Same thing different syntax
Reply all
Reply to author
Forward
0 new messages