[xwiki-devs] Wiki Macro Bridge on 2.0M2 for Groovy (was Re: Macros and JavaScript working together (was Re: [DISCUSSION] XWiki Chart Api & Chart Macro))
On Tue, Aug 4, 2009 at 9:29 AM, Asiri Rathnayake <[email protected]
wrote:
The wiki macro bridge has been released with 2.0M2. ...
If you come across any problems while you are at it, we can improve wiki macro bridge :)
Thanks for reminding me about the Xwiki macro bridge. Looks great and is a big improvement over how things were done previously. Your message was timely as helped me answer one of my big questions about having groovy or clojure macros available on virtual-wiki setup: http://platform.xwiki.org/xwiki/bin/view/DevGuide/WikiMacroTutorial - Wiki macro authors need to have programming rights - Wiki macros can only be defined inside the main wiki, though they can be used throughout a farm I wrote my first macro-bridge macro (see attachment Main.TestMacroBridge.xar ) in groovy in preparation for my experiments with scripting in Clojure. The hardest thing was finding out that the name of "context" had changed to "xcontext" for groovy and other JSR-223 languages, whereas velocity (and WikiMacroTutorial) uses "context". This has been discussed on the lists ( http://markmail.org/message/o2trzrnv5xts6x6v ), and the WikiMacroTutorial needs updating to reflect the final status & naming-conventions. My macro is quite simple. but does a lot, taken from here: http://www.ibm.com/developerworks/java/library/j-pg05199/index.html Usage: {{weather_by_zip zip=92625 /}} Code: ............................... Objects of type XWiki.WikiMacroClass WikiMacroClass 0: weather_by_zip {{script language=groovy}} def rss = new XmlSlurper().parseText((" http://weather.yahooapis.com/forecastrss?p=" + xcontext.macro.params.zip).toURL().text) println rss.channel.title println "Sunrise: ${rss.channel.astronomy.@sunrise}" println "Sunset: ${rss.channel.astronomy.@sunset}" println "Currently:" println "\t" + rss.channel.item.condition.@date println "\t" + rss.channel.item.condition.@temp println "\t" + rss.channel.item.condition.@text {{/script}} Objects of type XWiki.WikiMacroParameterClass WikiMacroParameterClass 0: zip ............................... May be you can put it to test by trying to implement your chart macro ;) It would be more useful to offer all-new Exhibit<http://www.simile-widgets.org/exhibit/> functionality with tighter integration into the Xwiki back-end, e.g. having document/space and other Xwiki "model" information abstractly available to an Exhibit-based "view/controller" to provide a "faceted views" presentation of Xwiki documents and contents. FYI, My existing Exhibit integration with Xwiki demo: http://nielsmayer.com/xwiki/bin/view/Exhibit/Presidents4 (source: http://nielsmayer.com/xwiki/bin/download/Exhibit/Presidents4/Presidents4Pkg....) My main commitment right now is an experiment to see if I can get JSR223-supported Clojure scripting in Xwiki. This message didn't give me much hope of success right now ( http://groups.google.com/group/clojure/msg/ad811b69d448e3db ) but I'll give Clojure on Xwiki a try anyways, and revisit later if it's just a matter of getting more solid JSR223 support for Clojure as development progresses. Niels http://nielsmayer.com
On Wed, Aug 5, 2009 at 1:13 PM, Niels Mayer <[email protected]> wrote:
I wrote my first macro-bridge macro (see attachment Main.TestMacroBridge.xar ) in groovy in preparation for my experiments with scripting in Clojure. The hardest thing was finding out that the name of "context" had changed to "xcontext" for groovy and other JSR-223 languages, whereas velocity (and WikiMacroTutorial<http://platform.xwiki.org/xwiki/bin/view/DevGuide/WikiMacroTutorial>) uses "context". This has been discussed on the lists ( http://markmail.org/message/o2trzrnv5xts6x6v ), and the WikiMacroTutorial needs updating to reflect the final status & naming-conventions.
Actually, it's in the documentation for the GroovyMacro: http://code.xwiki.org/xwiki/bin/view/Macros/GroovyMacro Note that since context is a reserved binding in JSR-223 specifications used
for Scripting Macros, the XWiki Api Context is now accessible throught xcontext
What is the full list of globals bound for groovy? e.g. "request" "xwiki" "xcontext" etc. Are there any additional bindings when accessed through the macro-bridge? (other than "xcontext.macro.content" and "xcontext.macro.context"). Is there a way to access the parameters passed in to a "script" macro. If one sets extra parameters beyond the defined ones, e.g. "{{script language=groovy zip=92625}}" is there a way to access the "extra" "zip=92625" parameter passed in to the "script" macro? .... Also, the code I posted from "XWiki.WikiMacroClass WikiMacroClass 0: weather_by_zip" had its line-feeds removed "in transit". Here it is again, hopefully intact: {{script language=groovy}} def rss = new XmlSlurper().parseText(("
+
xcontext.macro.params.zip).toURL().text)
println rss.channel.title println "Sunrise: ${rss.channel.astronomy.@sunrise}" println "Sunset: ${rss.channel.astronomy.@sunset}" println "Currently:" println "\t" + rss.channel.item.condition.@date println "\t" + rss.channel.item.condition.@temp println "\t" + rss.channel.item.condition.@text {{/script}} Same example, in the form of a 2.0 document w/o macro bridge. using "request.zip" to pass parameter to groovy: == Groovy Example From [[IBM DeveloperWorks>>
http://www.ibm.com/developerworks/java/library/j-pg05199/index.html]]==
Note: correct usage requres {{code}}request.zip{{/code}} parameter, e.g [[92625>>Main.GroovyTest3?zip=92625]] [[92660>>Main.GroovyTest3?zip=92660]] [[10001>>Main.GroovyTest3?zip=10001]]...
{{groovy}}
def rss = new XmlSlurper().parseText(("
+ request.zip).toURL().text) println rss.channel.title println "Sunrise: ${rss.channel.astronomy.@sunrise}" println "Sunset: ${rss.channel.astronomy.@sunset}" println "Currently:" println "\t" + rss.channel.item.condition.@date println "\t" + rss.channel.item.condition.@temp println "\t" + rss.channel.item.condition.@text {{/groovy}} -- Niels http://nielsmayer.com
Hi Neils, On Thu, Aug 6, 2009 at 1:43 AM, Niels Mayer <[email protected]> wrote:
On Tue, Aug 4, 2009 at 9:29 AM, Asiri Rathnayake < [email protected]> wrote:
The wiki macro bridge has been released with 2.0M2. ...
If you come across any problems while you are at it, we can improve wiki macro bridge :)
Thanks for reminding me about the Xwiki macro bridge. Looks great and is a big improvement over how things were done previously. Your message was timely as helped me answer one of my big questions about having groovy or clojure macros available on virtual-wiki setup: http://platform.xwiki.org/xwiki/bin/view/DevGuide/WikiMacroTutorial
- Wiki macro authors need to have programming rights - Wiki macros can only be defined inside the main wiki, though they can be used throughout a farm
I wrote my first macro-bridge macro (see attachment Main.TestMacroBridge.xar ) in groovy in preparation for my experiments with scripting in Clojure. The hardest thing was finding out that the name of "context" had changed to "xcontext" for groovy and other JSR-223 languages, whereas velocity (and WikiMacroTutorial) uses "context". This has been discussed on the lists ( http://markmail.org/message/o2trzrnv5xts6x6v ), and the WikiMacroTutorial needs updating to reflect the final status & naming-conventions.
My macro is quite simple. but does a lot, taken from here: http://www.ibm.com/developerworks/java/library/j-pg05199/index.html Usage: {{weather_by_zip zip=92625 /}}
Just tested your macro. Great stuff!!! With a bit of styling (SSX) we could actually put your macro in http://code.xwiki.org/xwiki/bin/view/Macros/ I'll try to work on it if I get a chance. Thanks. - Asiri
Code: ............................... Objects of type XWiki.WikiMacroClass WikiMacroClass 0: weather_by_zip {{script language=groovy}} def rss = new XmlSlurper().parseText((" http://weather.yahooapis.com/forecastrss?p=" + xcontext.macro.params.zip).toURL().text) println rss.channel.title println "Sunrise: ${rss.channel.astronomy.@sunrise}" println "Sunset: ${rss.channel.astronomy.@sunset}" println "Currently:" println "\t" + rss.channel.item.condition.@date println "\t" + rss.channel.item.condition.@temp println "\t" + rss.channel.item.condition.@text {{/script}}
Objects of type XWiki.WikiMacroParameterClass WikiMacroParameterClass 0: zip ...............................
May be you can put it to test by trying to implement your chart macro ;)
It would be more useful to offer all-new Exhibit<http://www.simile-widgets.org/exhibit/> functionality with tighter integration into the Xwiki back-end, e.g. having document/space and other Xwiki "model" information abstractly available to an Exhibit-based "view/controller" to provide a "faceted views" presentation of Xwiki documents and contents. FYI, My existing Exhibit integration with Xwiki demo: http://nielsmayer.com/xwiki/bin/view/Exhibit/Presidents4 (source: http://nielsmayer.com/xwiki/bin/download/Exhibit/Presidents4/Presidents4Pkg....)
My main commitment right now is an experiment to see if I can get JSR223-supported Clojure scripting in Xwiki. This message didn't give me much hope of success right now ( http://groups.google.com/group/clojure/msg/ad811b69d448e3db ) but I'll give Clojure on Xwiki a try anyways, and revisit later if it's just a matter of getting more solid JSR223 support for Clojure as development progresses.
Niels http://nielsmayer.com
http://jira.xwiki.org/jira/browse/XAWMB-2 2.0M2 XE release has a bug when using Groovy Macros in the 2.0 Macro Bridge. To demonstrate this bug, see attached http://jira.xwiki.org/jira/secure/attachment/15573/GroovyRandomMacroPkg.xar 2400 08-09-09 14:25 Macros/WebHome.xml 7032 08-09-09 14:25 Macros/GroovyRandom.xml 3131 08-09-09 14:25 Macros/GroovyRandomTest.xml 7387 08-09-09 14:25 Macros/Weather.xml 2177 08-09-09 14:25 Macros/WeatherMacroTest.xml 1050 08-09-09 14:25 package.xml In order to get the attached groovy scripts to work with the 2.0 Macro Bridge, in xwiki:XWiki.XWikiPreferences?editor=globaladmin§ion=Programming, the "Groovy Macro Pages" field must be set to "Macros.Weather,Macros.GroovyRandom". When xwiki.virtual=1 there is a bug that you need to have documents Macros.Weather and Macros.GroovyRandom on the VIRTUAL HOST, and owned by the "root" wiki admin xwiki:XWiki.Admin. If this isn't done, you get a "inadequate access privileges" error on the groovy script, unless you're running the script on the root wiki. Furthermore, these local macro-bridge documents do not override or change the original root-wiki definition setup in the xwiki:XWiki.XWikiPreferences "Macros.Weather,Macros.GroovyRandom." In 2.0M2, you can use completely empty documents for this purpose, as long as they're owned by xwiki:XWiki.Admin. The need for these"shadow" documents in the virtual wiki is a bug; alternately, the fact that they do nothing in the virtual-wiki (they don't allow definition of any new local macros) is a bug as well. What makes sense is that if the virtual-wiki defines it's own <vhost>:XWiki.XWikiPreferences "Groovy Macro Pages" entries, and these are owned by xwiki:XWiki.Admin for "programming rigths" in a virtual wiki, then these scripts would override or take precedence over globally defined ones. In fact, if any locally defined scripts exist, they should be available on that v-host as long as they're owned by xwiki:XWiki.Admin for "programming rigths". A second Major bug in the wiki-macro bridge is that only the first invocation "works" – all subsequent invocations fail silently. As the only way to get output from these groovy scripts is to println, I'm wonderng whether the output stream gets closed after the first invocation, causing all subsequent invocations to go "silent". For example the following: == Testing 2.0 Macro groovy_random == 1. {{groovy_random size="66"/}} 1. {{groovy_random size="56"/}} 1. {{groovy_random size="46"/}} 1. {{groovy_random size="36"/}} 1. {{groovy_random size="26"/}} 1. {{groovy_random size="16"/}} 1. {{groovy_random size="6" /}} ... Produces the result: Testing 2.0 Macro groovy_random 1. p0NhDskfp3AXkjlL7qJKwErXuVSJMKLAGhwBPLhIminTLAc9qz8yVVFAY6DD5RF6GC 2. 3. 4. 5. 6. 7. ... Note that all the outputs subsequent to the first are empty. Last time I ran similar scripts in a non-virtual wiki, however, I believe all the outputs from each groovy script invocation occurred. By way of comparison, a number of Groovy Scripts that do not use the Wiki Macro Bridge were developed to see if the same issues arose in a virtual wiki. For example, multiple groovy scripts can be called sequentially in a document (sharing objects/variables between them), and all the outputs occur correctly, unlike above. Furthermore, no additional complications in installation occur: for example, the wiki macro bridge seems to require the "root wiki" be modified to contain macros even if you only want them on a single virtual host. This will make those macros available in all virtual-wikis, although the scripts will all fail unless xwiki:XWiki.Admin-owned "shadow documents" exist on all the virtual-host wikis. I think this behavior is a "bug". If scripts are to be made available across all wikis in a virtual-wiki setup, they should be defined on the root-wiki's xwiki:XWiki.XWikiPreferences -> Programming -> "Groovy Macro Pages". If they are to be available on a single virtual-wiki, as long as they're owned by the root xwiki:XWiki.Admin, they should be defined in <vhost>:XWiki.XWikiPreferences -> Programming -> "Groovy Macro Pages". FYI, here are the additional groovy scripts fin the second attachment, http://jira.xwiki.org/jira/secure/attachment/15574/GroovyExamplesPkg.xar 1776 08-09-09 14:58 Groovy/WebHome.xml 2318 08-09-09 14:58 Groovy/GroovyTest1.xml 2466 08-09-09 14:58 Groovy/GroovyTest3.xml 2643 08-09-09 14:58 Groovy/GroovyTest4.xml 3618 08-09-09 14:58 Groovy/SshHelperClass.xml 2129 08-09-09 14:58 Groovy/SshHelperTest.xml 2088 08-09-09 14:58 Groovy/TestClass1.xml 2148 08-09-09 14:58 Groovy/TestClass2.xml 2773 08-09-09 14:58 Groovy/VelocityCallingTestClass1.xml 2099 08-09-09 14:58 Groovy/VelocityCallingTestClass2.xml 1750 08-09-09 14:58 package.xml Niels http://nielsmayer.com
Also, by way of comparison, the "multiple invocation" bug doesn't happen using the "1.0 way" in a "2.0" document, without wiki-macro-bridge, using $xwiki.parseGroovyFromPage(). Is there a 2.0 equivalent for $xwiki.parseGroovyFromPage() method suggested by http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutor... http://jira.xwiki.org/jira/browse/XAWMB-2?focusedCommentId=43681&page=com.at... FYI, here, I demonstrate a "regular non macro bridge" way of invoking groovy in a 2.0 document. It doesn't have the same issues with only outputting the first instance results: == Testing parseGroovyFromPage("TestClass1") With 2.0 Syntax == Note that [[TestClass1?viewer=code]] is in 1.0 Syntax, per [[http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutor...]]. Is there a 2.0 syntax for $xwiki.parseGroovyFromPage()? ==== Initialize $groovyObject ==== {{velocity}} #set($groovyObject = $xwiki.parseGroovyFromPage("TestClass1")) $groovyObject.setObjects($xwiki, $context) {{/velocity}} ==== First Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Second Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Third Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Fourth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Fifth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Sixth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Seventh Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} Produces Testing parseGroovyFromPage("TestClass1") With 2.0 Syntax Note that TestClass1 is in 1.0 Syntax, per http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutor.... Is there a 2.0 syntax for $xwiki.parseGroovyFromPage()?Initialize $groovyObject First Call $groovyObject.helloWorld() Hello World:0 Second Call $groovyObject.helloWorld() Hello World:1 Third Call $groovyObject.helloWorld() Hello World:2 Fourth Call $groovyObject.helloWorld() Hello World:3 Fifth Call $groovyObject.helloWorld() Hello World:4 Sixth Call $groovyObject.helloWorld() Hello World:5 Seventh Call $groovyObject.helloWorld() Hello World:6 With the class defined in a 1.0 document: /* Groovy Class Called by [Groovy.VelocityCallingTestClass1] #* */ class groovyClass { def xwiki; def context; def call_count = 0; void setObjects(xwiki, context) { setXWiki(xwiki); setContext(context); } void setXWiki(xwiki) { this.xwiki = xwiki; } void setContext(context) { this.context = context; } String helloWorld() { return "Hello World:" + call_count++; } } /* *# */ Niels http://nielsmayer.com
Hi Neils, Many thanks for reporting this issue :) I have broken down your JIRA issue ( http://jira.xwiki.org/jira/browse/XAWMB-2) into two separate issues and moved them to correct projects / components as below: http://jira.xwiki.org/jira/browse/XWIKI-4140 (Fixed in 2.0M3) http://jira.xwiki.org/jira/browse/XWIKI-4141 And while fixing XWIKI-4140 I encountered another bug (not related to your JIRA) which I reported as: http://jira.xwiki.org/jira/browse/XE-475 About XWIKI-4141, you can use the {{groovy}} macro instead for now. - Asiri PS: The code in your Macros.GroovyRandom wiki macro is: {{script language=groovy}}xwiki.generateRandomString(xcontext.macro.params.size){{/script}} I had to change this to the following to make it work: {{script language=groovy}}println(xwiki.xwiki.generateRandomString(Integer.parseInt(xcontext.macro.params.size))){{/script}} On Mon, Aug 10, 2009 at 6:21 AM, Niels Mayer <[email protected]> wrote:
Also, by way of comparison, the "multiple invocation" bug doesn't happen using the "1.0 way" in a "2.0" document, without wiki-macro-bridge, using $xwiki.parseGroovyFromPage(). Is there a 2.0 equivalent for $xwiki.parseGroovyFromPage() method suggested by
http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutor... ?
http://jira.xwiki.org/jira/browse/XAWMB-2?focusedCommentId=43681&page=com.at... FYI, here, I demonstrate a "regular non macro bridge" way of invoking groovy in a 2.0 document. It doesn't have the same issues with only outputting the first instance results:
== Testing parseGroovyFromPage("TestClass1") With 2.0 Syntax ==
Note that [[TestClass1?viewer=code]] is in 1.0 Syntax, per [[ http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutorial]<http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutorial%5D> ]. Is there a 2.0 syntax for $xwiki.parseGroovyFromPage()? ==== Initialize $groovyObject ==== {{velocity}} #set($groovyObject = $xwiki.parseGroovyFromPage("TestClass1")) $groovyObject.setObjects($xwiki, $context) {{/velocity}} ==== First Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Second Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Third Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Fourth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Fifth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Sixth Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}} ==== Seventh Call $groovyObject.helloWorld() ==== {{velocity}}$groovyObject.helloWorld(){{/velocity}}
Produces
Testing parseGroovyFromPage("TestClass1") With 2.0 Syntax Note that TestClass1 is in 1.0 Syntax, per
http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutor... . Is there a 2.0 syntax for $xwiki.parseGroovyFromPage()?Initialize $groovyObject First Call $groovyObject.helloWorld() Hello World:0 Second Call $groovyObject.helloWorld() Hello World:1 Third Call $groovyObject.helloWorld() Hello World:2 Fourth Call $groovyObject.helloWorld() Hello World:3 Fifth Call $groovyObject.helloWorld() Hello World:4 Sixth Call $groovyObject.helloWorld() Hello World:5 Seventh Call $groovyObject.helloWorld() Hello World:6
With the class defined in a 1.0 document:
/* Groovy Class Called by [Groovy.VelocityCallingTestClass1] #* */
class groovyClass {
def xwiki; def context; def call_count = 0;
void setObjects(xwiki, context) { setXWiki(xwiki); setContext(context); }
void setXWiki(xwiki) { this.xwiki = xwiki; }
void setContext(context) { this.context = context; }
String helloWorld() { return "Hello World:" + call_count++; } }
/* *# */
Niels http://nielsmayer.com _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
participants (2)
-
Asiri Rathnayake -
Niels Mayer