Helma Logo
main list history

Version 25 by zumbrunn on 19. December 2005, 11:02

45Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "ifcheck" and "forloop" attributes and then evaluate them in the context of "that".
47When parsing the "forloop" attributes, Helma would loop through the indicated object (topics) with <nobr>"for(var $topics in topics)"</nobr> and repeat the specified element (the table row) with <nobr>topics$ == topics[$topics]</nobr>

Version 24 by zumbrunn on 19. December 2005, 10:48

15        <tr ifcheck="topics"
19        <tr forloop="topics" class="rowcolor{ $topics %% 'rowcolor'+ ($topics % 2 }2) %%"
20            <td>{ <td>%% topics$.name }</td>%%</td>
21            <td ifcheck="!topics$topics$.countcount == 0" lookup="true"
22            <td if="topics$.count == 1" lookup="true">{ topics$.count } comment</td>  No comments yet</td>
23            <td ifcheck="topics$.count > == 1" lookup="true">{ topics$.count } comments</td>
24                %% topics$.count %% comment</td>
25            <td check="topics$.count > 1" lookup="true">
26                %% topics$.count %% comments</td>
21        <tr ifcheck="!topics"
22            <td colspan="2" align="center" lookup="true">This list is empty</td>
23                This list is empty</td>
43
44As a reality check for this proposal I so far came up with a specialized prototype of the rendering method. The idea seems to work quite nicely already with current builds of Helma 2. I thought E4X could make implementing this very easy, but I was surprised that it really turned out that way in practice:
45
46    function handle_get() {
47        // first prototype for the next incarnation of mocha objects
48        
49        // the render function, providing the magic
50        var render = function(view) {
51            // loop
52            var toLoop = view..*.(@loop.toSource() != '<></>');
53            for (var item in toLoop) {
54                var dataName = toLoop[item].@loop.toString();
55                delete toLoop[item].@loop;
56                var data = eval(dataName);
57                var stamp = toLoop[item].toString();
58                for (var i in data) {
59                    var stencil = stamp.replace(
60                        eval("/%% "+dataName+"\\$\\.(.+) %%/g"),
61                        '{ '+dataName+'['+i+'].$1 }'
62                    );
63                    stencil = stencil.replace(
64                        eval('/"'+dataName+'\\$/g'),
65                        '"'+dataName+'['+i+']'
66                    );
67                    stencil = stencil.replace(
68                        eval('/"%% (.*)\\$'+dataName+'(.*) %%"/g'),
69                        '{ $1'+i+'$2 }'
70                    );
71                    toLoop.parent().insertChildBefore(
72                        toLoop[item],
73                        eval(stencil)
74                    );
75                }
76                delete toLoop[item].parent().*[toLoop[item].childIndex()];
77            }
78           
79            // lookup
80            var toLookup = view..*.(@lookup.toSource() != '<></>');
81            for (var item in toLookup) {
82                delete toLookup[item].@lookup;
83                var lookedup = '('+toLookup[item].children()[0]+')';
84                toLookup[item].setChildren(lookedup);
85            }
86       
87            // check
88            var toCheck = view..*.(@check.toSource() != '<></>');
89            for (var item in toCheck) {
90                if (eval(toCheck[item].@check.toString()))
91                    delete toCheck[item].@check;
92                else
93                    toCheck[item] = '';
94            }
95            return view;
96        }
97       
98        // an example skin
99        var myview = <table border="1">
100            <tr check="topics">
101                <th lookup="true">Topic Name</th>
102                <th lookup="true">Comment Count</th>
103            </tr>
104            <tr loop="topics" class="%% 'rowcolor'+ ($topics % 2) %%">
105                <td>%% topics$.name %%</td>
106                <td check="topics$.count == 0" lookup="true">
107                    No comments yet</td>
108                <td check="topics$.count == 1" lookup="true">
109                    %% topics$.count %% comment</td>
110                <td check="topics$.count > 1" lookup="true">
111                    %% topics$.count %% comments</td>
112            </tr>
113            <tr check="!topics">
114                <td colspan="2" align="center" lookup="true">
115                    This list is empty</td>
116            </tr>
117        </table>;
118       
119        // the example data
120        var topics = [
121            {name : 'Peter', count : 0},
122            {name : 'Wolf', count : 2},
123            {name : 'John', count : 1},
124            {name : 'Andy', count : 8}
125        ];
126       
127        // rendering the list
128        var listtable = render(myview.copy());
129    
130        // rendering the empty table
131        topics = null;
132        var emptytable = render(myview.copy());
133       
134        // assembling the page
135        var page = <html><body>{ listtable }<hr/>{ emptytable }</body></html>;
136       
137        // writing the page source to the reponse buffer
138        res.contentType = "text/html";
139        res.write(page.toSource());
140    }
141
142Resulting in the following output:
143
144    <html>
145      <body>
146        <table border="1">
147          <tr>
148            <th>(Topic Name)</th>
149            <th>(Comment Count)</th>
150          </tr>
151          <tr class="rowcolor0">
152    
153            <td>Peter</td>
154            <td>(No comments yet)</td>
155          </tr>
156          <tr class="rowcolor1">
157            <td>Wolf</td>
158            <td>(2 comments)</td>
159          </tr>
160    
161          <tr class="rowcolor0">
162            <td>John</td>
163            <td>(1 comment)</td>
164          </tr>
165          <tr class="rowcolor1">
166            <td>Andy</td>
167            <td>(8 comments)</td>
168    
169          </tr>
170        </table>
171        <hr/>
172        <table border="1">
173          <tr>
174            <td colspan="2" align="center">
175                (This list is empty)</td>
176          </tr>
177        </table>
178    
179      </body>
180    </html>
181

Version 23 by zumbrunn on 07. December 2005, 16:18

47this.controls.list would be the function that is called in order to handle the request, similar to todays this.list_action.

Version 22 by zumbrunn on 07. December 2005, 16:15

19        <tr for="topics" class="rowcolor{($topics rowcolor{ $topics % 2)}2 }"
20            <td>topics$<td>{ topics$.name</td>name }</td>
21            <td if="topics$.count == 1" lookup="true">topics$>{ topics$.count } comment</td>
22            <td if="topics$.count > 1" lookup="true">topics$>{ topics$.count } comments</td>

Version 21 by zumbrunn on 07. December 2005, 16:03

43When parsing the "for" attributes, Helma would loop through the indicated object (topics) with <nobr>for(var $foo <nobr>"for(var $topics in foo)</nobr> topics)"</nobr> and repeat the specified element (the table row) with <nobr>foo$ <nobr>topics$ == foo[$foo]</nobr>topics[$topics]</nobr>

Version 20 by zumbrunn on 07. December 2005, 16:00

43When parsing the "for" attributes, Helma would loop through the indicated object (topics) with <nobr>for(var $foo in foo)</nobr> and repeat the specified element (the table row) with <nobr>foo$ == foo[$foo]</nobr>

Version 19 by zumbrunn on 07. December 2005, 15:56

3    // function at Site.prototype.views.list.controlcontrol(that)
32    // function at Site.prototype.controls.list
39Sitethis.views.list.control(that) control() is invoked whenever when the list view is rendered. When it is invoked, "that" is the object which was passed as parameter of the render() method or otherwise an empty/default object. "that" is the object that will be used as the Javascript context when rendering the view.
47this.controls.list would the function that is called in order to handle the request, similar to todays this.list_action.

Version 18 by zumbrunn on 07. December 2005, 15:41

1./Site/topiclist/Site/list.view.handlercontrol
3    // function at Site.views.list.control
12./Site/topiclist/Site/list.view
32    // function at Site.controls.list
34        main : this.renderView('topiclist'views.list.render()
36    var page = thisPage.renderView(Page.views.default, content);.render(content);
39The handler Site.views.list.control(that) is invoked whenever the topiclist list view is rendered. When the handler it is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) the render() method or otherwise an empty/default object. It "that" is the object that will be used as the current and only accessible scope Javascript context when rendering the view.

Version 17 by zumbrunn on 07. December 2005, 14:49

39Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object with <nobr>for(var $foo in foo)</nobr> and repeat the specified element, with <nobr>foo$ == foo[$foo]</nobr>
40
41When parsing the "for" attributes, Helma would loop through the indicated object with <nobr>for(var $foo in foo)</nobr> and repeat the specified element with <nobr>foo$ == foo[$foo]</nobr>
42
43When parsing the "lookup" attributes, Helma would check if a lookup handler function exists and if so would apply it to the element's content.

Version 16 by zumbrunn on 07. December 2005, 14:41

1
37

Version 15 by zumbrunn on 07. December 2005, 14:41

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object with <nobr>for(var $foo in foo)</nobr> and repeat the specified element, with <nobr>foo$ == foo[$foo]</nobr>
39
40The handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or otherwise an empty/default object. It is the object that will be used as the current and only accessible scope when rendering the view.
41
42Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object with <nobr>for(var $foo in foo)</nobr> and repeat the specified element, with <nobr>foo$ == foo[$foo]</nobr>

Version 14 by zumbrunn on 07. December 2005, 14:38

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object with for(var <nobr>for(var $foo in foo) foo)</nobr> and repeat the specified element, with foo$ <nobr>foo$ == foo[$foo]foo[$foo]</nobr>

Version 13 by zumbrunn on 07. December 2005, 14:37

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object (foo) with for(var $foo in foo) and repeat the specified element, substituting foo$.bar with foo$ == foo[$foo]

Version 12 by zumbrunn on 07. December 2005, 14:32

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object (foo) and repeat the specified element, substituting foo$bar foo$.bar with foo[$]foo[$foo].bar.

Version 11 by zumbrunn on 07. December 2005, 14:31

20        <tr for="topics" class="rowcolor{(topics$ rowcolor{($topics % 2)}"
21            <td>topics$name</td><td>topics$.name</td>
22            <td if="!topics$count!topics$.count" lookup="true">No comments yet</td>
23            <td if="topics$count topics$.count == 1" lookup="true">topics$count >topics$.count comment</td>
24            <td if="topics$count topics$.count > 1" lookup="true">topics$count >topics$.count comments</td>

Version 10 by zumbrunn on 07. December 2005, 12:19

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object (foo) and repeat the specified element, substituting $bar$ foo$bar with foo[$].bar.
20        <tr for="topics" class="rowcolor{($ rowcolor{(topics$ % 2)}"
21            <td>$name$</td><td>topics$name</td>
22            <td if="!$count$!topics$count" lookup="true">No comments yet</td>
23            <td if="$count$ topics$count == 1" lookup="true">$count$ >topics$count comment</td>
24            <td if="$count$ topics$count > 1" lookup="true">$count$ >topics$count comments</td>

Version 9 by zumbrunn on 07. December 2005, 12:08

20        <tr for="topics" class="rowcolor{($ % 2)}"

Version 8 by zumbrunn on 07. December 2005, 12:07

20        <tr for="topics" class="rowcolor{($count$ % 2)}"

Version 7 by zumbrunn on 07. December 2005, 12:03

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that". When parsing the "for" attributes, Helma would loop through the indicated object (foo) and repeat the specified element, substituting $bar$ with foo[$].bar.

Version 6 by zumbrunn on 07. December 2005, 11:55

20        <tr for="topics" class="rowcolor{($count$ % 2)}"

Version 5 by zumbrunn on 07. December 2005, 11:45

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects. When Helma would render these views, it would parse them for "lookup", "if" and "for" attributes and then evaluate them in the context of "that".

Version 4 by zumbrunn on 07. December 2005, 11:43

1This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view. Views would be E4X Javascript XML objects.
2
11
12This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view.

Version 3 by zumbrunn on 07. December 2005, 11:40

11This handler is invoked whenever the topiclist view is rendered. When the handler is invoked, "that" is the object which was passed as the second parameter of renderView(view,that)that) or an empty/default object otherwise. It is the object that will be used as the current and only accessible scope when rendering the view.

Version 2 by zumbrunn on 07. December 2005, 11:37

1
11
12This handler is invoked whenever the topiclist view is rendered. "that" is the object which was passed as the second parameter of renderView(view,that). It is the object that will be used as the current and only accessible scope when rendering the view.

Version 1 by zumbrunn on 07. December 2005, 11:30

2./Site/topiclist.view.handler
3
4    if (this.topics.count()) {
5        that.topics = {};
6        for (var topic in this.topics) {
7            that.topics.name = this.topics[topic].name;
8            that.topics.count = this.topics[topic].comments.count();
9        }
10    }
11
12./Site/topiclist.view
13
14    <table border="1">
15        <tr if="topics">
16            <th lookup="true">Topic Name</th>
17            <th lookup="true">Comment Count</th>
18        </tr>
19        <tr for="topics">
20            <td>$name$</td>
21            <td if="!$count$" lookup="true">No comments yet</td>
22            <td if="$count$ == 1" lookup="true">$count$ comment</td>
23            <td if="$count$ > 1" lookup="true">$count$ comments</td>
24        </tr>
25        <tr if="!topics">
26            <td colspan="2" align="center" lookup="true">This list is empty</td>
27        </tr>
28    </table>
29
30./Site/list.control
31
32    var content = {
33        main : this.renderView('topiclist')
34    };
35    var page = this.renderView(Page.views.default, content);
36    return page;
37
38