Ringobot log - RingoJS IRC channel: #ringojs on irc.freenode.net

2010-06-05:

[0:22] <oravecz> context = {
[0:22] <oravecz> s_macro: function(macro, context, skin) skin.renderSubskin('sub')
[0:22] <oravecz> };
[0:22] <oravecz> that's from the skin test...2 questions
[0:22] <oravecz> 1. Is leaving the curlies off a JS 1.8 thing?
[0:22] <oravecz> 2. Does this function get executed by a skin somehow?
[0:34] <hannesw_> yes to both
[0:47] <oravecz> thx for the answers. Looking at the code for the built-in 'if' macro, I don't see support for blocks. Is this accurate?
[0:51] <oravecz> ok, the macro support is pretty cool in the skins
[0:53] <oravecz> I can see a need for some global macros that aren't part of the context object. Things like formatting dates or currency and such. Is there a way to add these or is it not doable because the 'builtin' var in skin.js is not exported?
[1:08] <hannesw_> oravecz we don't have blocks, we have subskins
[1:08] <hannesw_> it's kind of like external blocks
[1:08] <oravecz> ok, i will try to get my head around that
[1:10] <oravecz> I was having a hard time creating a list using something simple like this: <ul>
[1:10] <oravecz> <% for name in <% names %> <li><% name %></li> %>
[1:10] <oravecz> </ul>
[1:10] <hannesw_> better use subskins for that
[1:11] <oravecz> so what does the skin engine do with what follows the for ... in?
[1:12] <hannesw_> it tries to resolve it against the context
[1:13] <hannesw_> so if you want to have literal text in there you have to use subskins
[1:13] <hannesw_> looking for an example...
[1:14] <hannesw_> demo app has a good overview: http://ringojs.org/demo/skins
[1:15] <hannesw_> or a real world example in jsdoc app:
[1:15] <hannesw_> http://github.com/ringo/ringojs/blob/master/apps/jsdoc/skins/module.html#L53-60
[1:16] <hannesw_> basically you do <% for x in <% y %> render foo %>
[1:16] <hannesw_> where foo is a subskin defined as
[1:16] <hannesw_> <% subskin foo %>
[1:16] <hannesw_> ....
[1:17] <earl> oravecz: regarding your formatting needs, we have filters for that
[1:19] <earl> <% record.datetime
[1:19] <earl> <% record.datetime | dateFormat "%Y-%m-%d" %> for example
[1:32] <oravecz> thx earl
[1:37] <oravecz> how about the ? regarding adding to the builtin macros? Any way to do that?
[1:44] <hannesw_> didn't understand that one
[1:53] <earl> oravecz: you can just use user-defined macros
[1:53] <earl> in general there shouldn't be a need to extend the set of builtin macros
[1:54] <earl> but this may be relaxed in the future. parts of the skin system are up for a rewrite
[1:54] <oravecz> so how do I add new filters or macros that are available globally?
[1:55] <earl> you hook them up in your config.js
[1:56] <oravecz> is there an example? (i.e. builtin doesn't look like it is exported in skin.js)
[1:56] <earl> iirc, the jsdoc app does this
[1:57] <earl> http://github.com/ringo/ringojs/blob/master/apps/jsdoc/config.js#L31
[1:57] <earl> you export a "macros" array in your config
[1:57] <earl> which is a list of modules (or module names)
[1:57] <earl> http://github.com/ringo/ringojs/blob/master/apps/jsdoc/helpers.js
[1:57] <oravecz> thx earl, can I do the same with filters somehow?
[1:58] <oravecz> oh, i see
[1:58] <earl> yeah, have a look at helpers.js
[1:58] <oravecz> the markdown integration is pretty cool too
[1:58] <oravecz> u guys seem so much further along than node and narwhal, but they get most the press :)
[1:59] <earl> well :)
[2:01] <oravecz> In the filter, you are writing directly to the buffer. Would it be possible to use the skin engine from within the filter?
[2:01] <earl> yes, it should be
[2:02] <earl> (if it is not, it is a bug)
[2:02] <oravecz> :)
[2:03] <earl> ringowiki may be a better example
[2:03] <earl> http://github.com/ringo/ringowiki/blob/master/helpers.js
[2:04] <oravecz> yeah, that's nice
[2:05] <oravecz> well, I got our ringo app integrated with maven with integration testing using jsunit and selenium
[2:06] <earl> very nice :)
[2:09] <oravecz> since ringo has its own structure that is not conducive to the WAR format I had to blow it apart a bit: http://gist.github.com/426223
[2:09] <oravecz> With that in place, you can do things like mvn jetty:run and mvn package (to generate a WAR file)
[2:10] <oravecz> And of course, mvn integration-test, to start the web server, run all tests, generate an HTML report, and shut down cleanly
[2:17] <hannesw_> oravecz: cool
[2:19] <hannesw_> what type of file is this? it's not a pom, right?
[2:20] <oravecz> it's part of the pom
[2:20] <oravecz> It's basically an Ant task embedded in the Maven lifecycle. It fires very early in the lifecycle.
[2:22] <oravecz> I maintain a clean checkout of RingoJS in my project hierarchy, and use that Ant task to copy the relevant directories from RingoJS to the places Maven expects to find such things.
[2:23] <oravecz> I can update ringo using git and then the next time I run maven it will copy over the files that changed.
[2:26] <hannesw_> we could put that pom into ringojs, right?
[2:28] <oravecz> yes, ringojs could be launched that way
[2:29] <hannesw_> gotta go
[2:29] <hannesw_> hope to see you around
[2:30] <oravecz> we're building a huge project on ringojs so u will see me more :)
[2:30] <oravecz> thx for the assitance tonite
[10:30] <ringostarr> 9fc2ae8 George Moschovitis: Added system.exit()
[15:13] <oravecz> Skin question... my context: { fields: ['a', 'b', 'c'] } is passed to a skin. I would like to render it like this: <p>a, b, c</p>
[15:13] <oravecz> I can do this by adding a function to my context which returns fields.join(', ')
[15:14] <oravecz> But is there any way to perform this JS in the skin definition as opposed to the context object. (Without having to create a global macro)
[15:33] <robi42> oravecz, there's an example of how one could do this in skin module's tests, see: http://github.com/ringo/ringojs/blob/master/test/ringo/skin_test.js#L116-L118
[15:34] <oravecz> thanks robi, i guess my real question was whether I can execute js in the skin somehow.
[15:35] <oravecz> that's a pretty cool link though
[15:35] <oravecz> (the way it highlights a section of the code)
[15:36] <oravecz> I may take a look at EJS as a way of integrating JS in my skins/templates
[15:36] <robi42> if you'd like to execute any js code logic inside a skin what you probably actually want is a macro, i guess
[15:36] <oravecz> right, I suppose I could create a filter also
[15:37] <robi42> in fact
[15:37] * robi42 afk now
[15:37] <oravecz> I just find the inability to pass parameters to filters and macros will be a stumbling block in the future
[15:52] <earl> oravecz: you can certainly pass parameters to filters and macros
[15:55] <earl> interestingly enough, we don't have a testcase for that yet
[15:56] <earl> but basically a simple macro which just prints its first parameter would be: `function foo_macro(macro) macro.parameters[0]`
[15:56] <earl> regarding your original a,b,c example, you could also do this with the echo builtin
[15:57] <earl> <% echo wrap=["<p>","</p>"] separator=", " fields %>
[16:11] <oravecz> hmm, i tried printing out the parameters passed to a macro, but the first argument was ({})
[16:11] <oravecz> perhaps I wasn't passing them correctly
[16:11] <oravecz> I was using: <% test a b c %>
[16:24] <oravecz> Interesting, calling <% test param=['a', 'b', 'c'] 'd' %> results in the first parameter returning this: {"name":"test","parameters":{"0":"d"},"parameterNames":["param"]}
[16:26] <oravecz> then macro.getParameter(index|key) returns the value of named parameters
[16:40] <oravecz> i'm trying to create a skin that renders recursively. In the skin is there a way to reference the context object passed in?
[20:09] <oravecz> in the skin's for ... in macro, it seems like it will iterate the properties on a js object. However, it only seems to return the values. Is it possible to get the name of each property?
[20:43] <oravecz> OK, looks like there is a property called 'index' that holds the name of each property
[21:40] <ringostarr> 472f0f6 Andreas Bolka: Test macro/filter parameter handling
[21:53] <oravecz> is there a way to evaluate js in a skin? For example, I can't get <% if <expr> render <subskin> %> to work if I replace <expr> with <% items.length > 10 %>.
[21:54] <earl> write a macro which does the items.length > 10 comparison
[21:54] <earl> or provide a separate boolean field along with the items array
[21:57] <oravecz> the skin functionality is really cool. Tacking on the Markdown java library exposed as a simple filter show the real power.
[21:58] <oravecz> But, not being able to evaluate javascript in the expression field of the 'if' macro is a real problem.
[22:02] <oravecz> the other template engines which can do this (ejs, moustache) are simple enough, but I hate to lose the other features of skins that already exist.
[22:03] <oravecz> I can try integrating EJS, but I have a question. If I have a Resource, how do I get a text string representation of that resource?
[22:03] <earl> we consider not being able to evaluate JS in the templates a feature
[22:03] <oravecz> haha
[22:03] <oravecz> yeah, the same way the moustache ppl feel that not supporting dor '.' notation is a feature
[22:04] <oravecz> *dot
[22:04] <earl> and i don't think mustache behaves the same for ifs, in this regard
[22:04] <earl> ahem
[22:04] <earl> actually, i think mustache does the same as ringo's skins
[22:04] <oravecz> close, but they support a block concept with their conditionals
[22:05] <earl> so do we
[22:05] <earl> <% if <% value %> render subskin %>
[22:05] <oravecz> well, inline blocks then as opposed to subskins
[22:05] <robi42> btw, one could also write a rather generic `condition` macro which, e.g., would look something like that then: <% if <% condition 'item.length > 10' %> render foo %>
[22:06] <earl> fortunately, one can not, at the moment :)
[22:06] <oravecz> I'm not opposed to subskins or macros, but it becomes irksome to keep adding functions/conditions to the context especially when the same context can be used for many views
[22:07] <robi42> well, ok, sry for spreading wrong info then :)
[22:07] <earl> user-defined macros can currently not do conditional rendering :)
[22:07] <earl> oravecz: well, macros are supposed to hold "view logic"
[22:10] <earl> the intended flow for ringo skins is that you prepare a "data object" (the context) and the skin then does simple rendering of this data
[22:10] <oravecz> well, sure :)
[22:11] <oravecz> my proof of concept is auto-generating documentation from our json-schema documents
[22:11] <earl> so if you need to do an "items.length>10" check in your skin, it's probably best to think what you need this condition for and then introduce an appropriately-named field in your context
[22:12] <oravecz> A json-schema document looks like this: http://json-schema.org/address
[22:12] <oravecz> Think of a view that takes that object as its context and renders out some html docs.
[22:13] <earl> shouldn't be a problem :)
[22:14] <oravecz> u guys have given me a lot of undoc'd things this morning (appreciate it) and I looked into the ringo skinning and macro code, but there are some holes I think.
[22:14] <oravecz> First problem here is iterating over the properties in the root of the object. Is there a built-in property that represents the context object?
[22:15] <earl> but if you want to do fancy stuff with it, you'll most likely need to preprocess this "data object" into a "view object"
[22:15] <earl> <% properties %> should do?
[22:15] <earl> but you should probably really pass this schema object as e.g. "data" in the context
[22:16] <earl> i.e. sthg like `render(skin, {data: getSchemaObject()})`
[22:16] <oravecz> <% for prop in <% properties %> do something %> does not iterate the root properties.
[22:17] <oravecz> a feature request might be to expose the context object as '_context', or something like that
[22:17] <oravecz> that would allow me to not have to create another object to hold my context just so I can reference the context.
[22:18] <earl> hmm, the <%for%> you posted above should do just what you need
[22:18] <oravecz> <% properties %> refers to the <root>.properties property. It doesn't contain 'description' or 'type'.
[22:19] <earl> yeah, is that not what you want?
[22:19] <earl> ah, i see, you want to iterate over the keys of the context object
[22:19] <oravecz> yes
[22:20] <oravecz> json-schemas can get quite large and are nested which requires a recursive process to render in the view
[22:20] <earl> i don't think that works even for normal objects
[22:21] <earl> ah, funnily enough it does
[22:22] <earl> there's no way to get the property-name, though
[22:22] <earl> ah, that's the <%index%> you mentioned earlier
[22:22] <earl> well
[22:22] <oravecz> yes
[22:23] <oravecz> surpirsed me too
[22:23] <earl> well
[22:23] <earl> don't directly use the schema as context, but wrap it as one property
[22:23] <oravecz> instead of using {data: schema} as my context, I did this:
[22:24] <oravecz> schema._context = schema
[22:24] <oravecz> now I can iterate root properties using: <% for prop in <% _context %> render property %>
[22:24] <earl> also an option
[22:24] <earl> the other way round probably makes more sense, though
[22:24] <earl> that way you won't have any problems adding macros/filters
[22:25] <oravecz> what would make more sense is adding support for _context in ringo :)
[22:25] <earl> well, i actually don't think so
[22:25] <oravecz> I don't disagree with you regarding the macros and filters
[22:25] <oravecz> it took me a while until I discovered that they are all copied from marious places onto the context object
[22:27] <oravecz> since that happens, it is a good reason why the user's context should be moved into a data property as you suggested earlier.
[22:27] <earl> yep, i think that's the way to go in this case
[22:27] <oravecz> i agree
[22:29] <oravecz> second problem I ran into is conditional behavior if my property is an object vs a primitive type. I can write a macro that returns a boolean depending on whether typeof returns 'object' or something else.
[22:29] <oravecz> so how can I get <% if %> to play nice with my macro?
[22:32] <earl> robi42: it seems i was wrong, i think you _could_ write such a super-if macro :)
[22:32] <earl> oravecz: what's the problem :) ?
[22:33] <robi42> earl: well, with some evil eval hack, i guess :)
[22:33] <oravecz> is robi's suggestion possible? <% if <% condition 'item.length > 10' %> render foo %>
[22:37] <oravecz> because I have to recurse when typeof === 'object'
[22:41] <earl> oravecz: let's try to solve it with a macro first :)
[22:42] <earl> eh, with a nnon-evil-hack-macro, that is
[22:42] <robi42> +1 :)
[22:45] <oravecz> here is my skin frag: <% if <% eq index 'properties' %> render Hello %>
[22:45] <oravecz> I don't think that passes <% index %> to my macro
[22:46] <oravecz> do I need it to read? <% if <% eq <% index %> 'properties' %> render Hello %>
[22:46] <earl> <% eq <% index %> properties %>
[22:46] <earl> <% eq <% index %> 'properties' %>
[22:47] <oravecz> okwhen I do that, this is the first argument to my macro: Macro: {"name":"eq","parameters":{"0":{"name":"index","parameters":{},"parameterNames":[]},"1":"properties"},"parameterNames":[]}
[22:48] <oravecz> The actual value of <% index %> is not passed in
[22:48] <earl> macros get three arguments: macro, context, skin
[22:48] <oravecz> right
[22:48] <oravecz> that was the 'macro' parameter
[22:48] <earl> call macro.parameters[0], and you should get the index value
[22:50] <oravecz> that returns [MacroTag index []{}]
[22:50] <earl> then you are running an old version of ringo :)
[22:50] <oravecz> no, latest
[22:51] <earl> 0.5 or git master?
[22:51] <oravecz> if I strigify it, I get {"name":"index","parameters":{},"parameterNames":[]}
[22:51] <oravecz> master
[22:52] <earl> hmm, that shouldn't be the case
[22:54] <oravecz> this is my macro right now...
[22:54] <oravecz> eq_macro = function(macro, context, skin) {
[22:54] <oravecz> log.warn('Macro: ' + JSON.stringify(macro));
[22:54] <oravecz> log.warn('Macro[0]: ' + JSON.stringify(macro.parameters[0]));
[22:54] <oravecz> return true;
[22:54] <oravecz> };
[22:54] <oravecz> And this is how I call it: <% if <% eq <% index %> 'properties' %> render foo %>
[22:55] <oravecz> I output <% index %> in my view and it is a text string like 'description'
[22:55] <robi42> btw, couldn't resist the hack: http://ringojs.pastebin.com/xcxZdCy3 :)
[22:56] <oravecz> is eval so terrible to use on the server side?
[22:56] <earl> yes
[22:56] <earl> and the whole idea is terrible :)
[22:56] <oravecz> :)
[22:57] <earl> k, macro calling works for me
[22:57] <earl> >> render(createSkin('<% for x in [a,b,c] render foo %><% subskin foo %><% fn <% index %> %>'), {fn_macro: function(macro) macro.parameters[0]})
[22:57] <earl> 012
[22:58] <earl> now let's see if that alsow works in if :)
[22:58] <earl> maybe 3-deep nsting is broken, who knows
[23:00] <earl> nope, works as expected
[23:00] <earl> var skin = createSkin('<% if <% even <% x %> %> echo "foo" %>')
[23:01] <robi42> that's great
[23:01] <earl> >> render(skin, {x: 1, even_macro: function (macro) (macro.parameters[0] % 2) == 0}) == ""
[23:01] <earl> true
[23:01] <earl> >> render(skin, {x: 2, even_macro: function (macro) (macro.parameters[0] % 2) == 0}) == "foo"
[23:01] <earl> true
[23:02] <earl> robi42: do you know httpclient usage by heart :) ?
[23:02] <oravecz> hrmm, so something is wrong with this? http://gist.github.com/427088
[23:03] <robi42> earl: depends, why?
[23:03] <earl> i'm just too lazy to look it up :)
[23:03] <earl> how do i fetch content from an url :) ?
[23:04] <earl> oravecz: nope, that macro looks good
[23:04] <oravecz> I am not using webapp.js (i have written my own rest.js). Perhaps the problem lies in there?
[23:04] <earl> i don't think so
[23:04] <earl> i _really_ looks like an old version or ringojs
[23:05] <earl> of*
[23:05] <earl> 809289526112ee8b8181a9718da89f26 modules/ringo/skin.js
[23:05] <earl> that's the md5sum of a current ringo/skin
[23:06] <earl> nested macros definitely won't work with 0.5
[23:07] <robi42> earl: `>> require('ringo/httpclient').get('http://example.com/').content`
[23:07] <earl> gracias :)
[23:07] <oravecz> i'm not a git guru, I do git fetch now
[23:11] <earl> git pull + ant jar
[23:12] <earl> or git fetch + git reset origin/master + ant jar
[23:12] <earl> or ... :)
[23:15] <earl> http://gist.github.com/raw/427093/96d2b48aab408d713e387fb5c5802c2e83068e8a/gistfile1.txt
[23:15] <earl> example output from ringo's shell running ringo master
[23:16] <oravecz> does calling .content on a Resource return the contents of that resource into a string?
[23:17] <earl> httpclient.get returns a special "response object"
[23:17] <earl> .content then returns the entity body as string (it seems)
[23:18] <earl> (but mind me, i hardly know httpclient :)
[23:18] <oravecz> cool
[23:19] <oravecz> well, i can't argue with your example :)
[23:19] <oravecz> I'm getting different results even after doing a git reset and rebuilding jar
[23:20] <oravecz> I will dig in...thanks for ur help
[23:20] <earl> something is probably using old module sources
[23:20] <earl> maybe you have a debian package install left over
[23:21] <oravecz> is there a new function or property I can check for?
[23:21] <earl> require.paths will show you what module path is used
[23:22] <earl> and to test for the specific behaviour at hand:
[23:22] <earl> >> include('ringo/skin'); render(createSkin('<% echo <% echo foo %> %>'))
[23:22] <earl> foo
[23:23] <earl> and old ringo/skin will give you something like [MacroTag echo ...]
[23:24] <oravecz> weird, foo shows up for me
[23:24] <earl> hmm
[23:24] <earl> well, maybe this peculiar case even works for old ringo/skin
[23:25] <earl> i think nested macros always worked for builtins
[23:25] <earl> so forget about the last check, that won't work :)
[23:25] <oravecz> ok
[23:27] <oravecz> gotta run, but i will compare your example and mine and see where the problem is
[23:27] <oravecz> thx for all ur help :)
[23:27] <earl> you're welcome