Link images with https source - orbeon

When I was trying to add an image to an orbeon form, I found that in some cases works fine, and in other does not.
For example, a simple code with a form that uses a remote image by URL:
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
<xh:head>
<xh:title>Form with Image by URL</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all">
<form>
<section-1>
<control-3>http://media2.giphy.com/avatars/aap/gjQXEptJHq99.gif</control-3>
</section-1>
</form>
</xf:instance>
<!-- Bindings -->
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="section-1-bind" name="section-1" ref="section-1">
<xf:bind id="control-3-bind" ref="control-3" name="control-3" type="xf:anyURI"/>
</xf:bind>
</xf:bind>
<!-- Metadata -->
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>UrlImage</application-name>
<form-name>UrlImage</form-name>
<title xml:lang="en">Form with Image by URL</title>
<description xml:lang="en"/>
<singleton>false</singleton>
</metadata>
</xf:instance>
<!-- Attachments -->
<xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
<attachments>
<css mediatype="text/css" filename="" size=""/>
<pdf mediatype="application/pdf" filename="" size=""/>
</attachments>
</xf:instance>
<!-- All form resources -->
<!-- Don't make readonly by default in case a service modifies the resources -->
<xf:instance id="fr-form-resources" xxf:readonly="false" xxf:exclude-result-prefixes="#all">
<resources>
<resource xml:lang="en">
<section-1>
<label>Untitled Section</label>
</section-1>
<control-3>
<label>This is a remote image</label>
</control-3>
</resource>
</resources>
</xf:instance>
<!-- Utility instances for services -->
<xf:instance id="fr-service-request-instance" xxf:exclude-result-prefixes="#all">
<request/>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:p="http://www.orbeon.com/oxf/pipeline">
<fr:section id="section-1-control" bind="section-1-bind">
<xf:label ref="$form-resources/section-1/label"/>
<fr:grid>
<xh:tr>
<xh:td>
<xf:output id="control-3-control" bind="control-3-bind" mediatype="image/*">
<xf:label ref="$form-resources/control-3/label"/>
<!-- No hint? -->
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:output>
</xh:td>
</xh:tr>
</fr:grid>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
The important part is the URL http://media2.giphy.com/avatars/aap/gjQXEptJHq99.gif, that works fine. But if you use a secure connection like https://media2.giphy.com/avatars/aap/gjQXEptJHq99.gif is not able to obtain the image.
I am not sure, maybe the problem is similar to this one Trusting all certificates using HttpClient over HTTPS
This is something that can be override by the configuration?
Can I use an image by using the URL from a https site without adding the certificate for each server in my java store?

There are properties to configure that, but you have to be careful, because in general you really shouldn't trust all certificates!
Your example of https://media2.giphy.com/avatars/aap/gjQXEptJHq99.gif works from Chrome without warning or error, for example, so I would expect it to work from the JVM as well. Maybe the JVM is not configured with the same set of CAs as the browser. In which case the JVM can be configured to add some, although it's a bit tricky.

Probably this behaviour is due to Orbeon does not uses the image URL directly, making a intermediate processing in the Orbeon "server-media".
Ok, seems that at the end, it only works if I add the certificate to the keystore of orbeon defined in oxf.http.ssl.keystore.uri. But this is only valid if I know the servers from where the images will be linked. Not a valid solution to link any image from any server. Java allows to disable this behaviour. Is it possible in Orbeon?

Related

Processing of HTTP status codes

I am creating forms in Orbeon 2021.1.2 PE and I have a problem with handling error calls. I'm creating HTTP service and Action via form builder. I hope to work it out and be able to stay with Builder.
I call API witch works similarly to Twitter, so it returns Error HTTP Status Codes also for business errors (see doc https://developer.twitter.com/ja/docs/basics/response-codes and https://developer.twitter.com/en/docs/twitter-ads-api/response-codes).
For easiest example: if I try to find something a if its not in database, I get code 404 with a detailed error in response body.
I need to get a status code + full body (headers will be good too) to the form. I don't want to use modal windows (witch is default in Orbeon) to handle this call. It disturb users + calls often changes the entire workflow (what is visible, etc.). Some calls are even asynchronous.
What is the best solution to this problem in Orbeon? I tried a few things and find block in several places.
1] Solution through property oxf.fr.detail.process.action-service-error.*.*
Here is set default error modal window. I deleted it and found that I can get some values and write them in the form, for example:
xf:setvalue(ref="//control-1", value="event('response-status-code')")
Specifically, these are the values:
event('error-type')
event('response-status-code')
event('resource-uri')
event('response-headers') - get specific via event('response-headers')[lower-case(name) = 'content-lenght']/value
event('response-body') - This not working, it is still supported?
Because it is a global configuration, I start to working where to put these values. I tried to create my own instance but ended up with the fr:insert() function.
I wanted to create a new instance for each submission and then enter separate values (event ('response-status-code'), ...). However, process with fr:insert() does not work and the documentation has poor example (https://doc.orbeon.com/form-runner/advanced/buttons-and-processes/actions-xforms#xf-insert)
This do what i want, but in form:
<xf:insert context="xxf:instance('HTTP-ERROR-RESULT')" ref="responses" origin="xxf:instance('HTTP-ERROR-TEMPLATE')"/>
I tried to transform it to process, but with no luck:
xf:insert(into="xxf:instance('HTTP-ERROR-RESULT')/reponses", origin="xxf:instance('HTTP-ERROR-TEMPLATE')")
If this is the right way? How to fix my semantic error in xf:insert() and how do I get response-body (event ('response-body') doesn't work...)? And is some way to get name of submission or action in process (I need some id for find in instance).
2] Another way I tried is through xforms-submit-error in submit but it didn't work too.
Under the structure of what the builder creates:
<xf:action event="xforms-submit-done" ev:observer="echo-submission">
<xf:action class="fr-set-control-value-action">
<xf:var name="control-name" value="'control-2'"/>
<xf:var name="control-value" value="/*"/>
</xf:action>
</xf:action>
I tried to insert the something similar but with xforms-submit-error:
<xf:action event="xforms-submit-error" ev:observer="echo-submission">
<xf:action class="fr-set-control-value-action">
<xf:var name="control-name" value="'control-2'"/>
<xf:var name="control-value" value="/*"/>
</xf:action>
</xf:action>
I found that when using class="fr-service" in submission, I cant catch xforms-submit-error. So is the right solution to write the whole submission yourself outside the builder and work with xforms-submit-error?
Or is there an another elegant solution in Orbeon? Thanks for any reply!
Writing your own XForms will give you the most flexibility. You can put that XForms either directly in the form definition, using Edit Source in Form Builder, or in a custom model, which is a file on disk on the server, which I would recommend, see doc.
You seem to have found all the pieces (you did some good research there!), but here is a summary. If you have a service my-service, you can listen to xforms-submit-error, and store the value of event attributes in your own instance. If using a custom model, that file would have the following content, and you can also put the content of the <xf:model> below directly inside the <xf:model> of the form definition through Edit Source in Form Builder. Here the logic just saves the status code in an instance my-error-instance, and then uses an <xf:message> to show if for debugging.
<xf:model xmlns:xf="http://www.w3.org/2002/xforms">
<xf:instance id="my-error-instance">
<_>
<status-code/>
</_>
</xf:instance>
<xf:action observer="my-service-submission" event="xforms-submit-error">
<xf:setvalue
ref="instance('my-error-instance')/status-code"
value="event('response-status-code')"/>
<xf:message value="instance('my-error-instance')/status-code"/>
</xf:action>
</xf:model>
You'll also want to disable the default dialog on errors by setting the following property.
<property as="xs:string" name="oxf.fr.detail.process.action-service-error.*.*"/>
Finally, I put below the full source of a form definition that you can use to test this, with a my-service HTTP service, making a request to http://httpbin.org/status/404, and called for form load, which I used to test the above custom model logic.
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
<xh:head>
<xh:title>Calling service returning a 404 on form load</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true" xxf:analysis.calculate="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all" xxf:index="id">
<form>
<section-1>
<grid-1>
<control-1/>
</grid-1>
</section-1>
</form>
</xf:instance>
<!-- Bindings -->
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="section-1-bind" name="section-1" ref="section-1">
<xf:bind id="grid-1-bind" ref="grid-1" name="grid-1">
<xf:bind id="control-1-bind" name="control-1" ref="control-1" xxf:whitespace="trim"/>
</xf:bind>
</xf:bind>
</xf:bind>
<!-- Metadata -->
<xf:instance id="fr-form-metadata" xxf:readonly="true" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>a</application-name>
<form-name>a</form-name>
<title xml:lang="en">Calling service returning a 404 on form load</title>
<description xml:lang="en"/>
<created-with-version>2021.1-SNAPSHOT PE</created-with-version>
<library-versions>
<app>4</app>
</library-versions>
</metadata>
</xf:instance>
<!-- Attachments -->
<xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
<attachments/>
</xf:instance>
<!-- All form resources -->
<xf:instance xxf:readonly="true" id="fr-form-resources" xxf:exclude-result-prefixes="#all">
<resources>
<resource xml:lang="en">
<section-1>
<label>Untitled Section</label>
</section-1>
<control-1>
<label/>
<hint/>
<alert/>
</control-1>
</resource>
</resources>
</xf:instance>
<xf:instance id="my-service-instance" class="fr-service" xxf:exclude-result-prefixes="#all">
<body xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
xmlns:fbf="java:org.orbeon.oxf.fb.FormBuilderXPathApi"><params/></body>
</xf:instance>
<xf:submission id="my-service-submission" class="fr-service"
resource="http://httpbin.org/status/404"
method="get"
serialization="none"
mediatype=""/>
<xf:action id="my-action-binding">
<xf:action event="fr-run-form-load-action-after-controls" ev:observer="fr-form-model"
if="true()">
<xf:send submission="my-service-submission"/>
</xf:action>
<xf:action event="xforms-submit" ev:observer="my-service-submission">
<xf:var name="request-instance-name" value="'my-service-instance'"/>
<xf:action/>
</xf:action>
<xf:action event="xforms-submit-done" ev:observer="my-service-submission"/>
</xf:action>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors">
<fr:section id="section-1-section" bind="section-1-bind">
<xf:label ref="$form-resources/section-1/label"/>
<fr:grid id="grid-1-grid" bind="grid-1-bind">
<fr:c y="1" x="1" w="6">
<xf:input id="control-1-control" bind="control-1-bind">
<xf:label ref="$form-resources/control-1/label"/>
<xf:hint ref="$form-resources/control-1/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</fr:c>
<fr:c y="1" x="7" w="6"/>
</fr:grid>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
Based on answers from #avernet I make generic handler for xforms-submit-error. First, as was said above, I disable the default dialog by set this property.
<property as="xs:string" name="oxf.fr.detail.process.action-service-error.*.*"/>
Then I put my own custom model to WEB-INF/resources/forms/resources. It's whole look this:
<xf:model xmlns:xf="http://www.w3.org/2002/xforms" id="my-model">
<xf:instance id="my-error-instance">
<reponseList>
</reponseList>
</xf:instance>
<xf:instance id="my-error-template-instance">
<submission name="">
<status-code/>
<uri/>
<date/>
</submission>
</xf:instance>
<xf:action observer="fr-form-model" event="xforms-submit-error">
<xf:insert if="not(exists(xxf:instance('my-error-instance')//submission[#name=event('target')]))" context="xxf:instance('my-error-instance')" ref="reponseList" origin="xxf:instance('my-error-template-instance')"/>
<xf:setvalue if="not(exists(xxf:instance('my-error-instance')//submission[#name=event('target')]))" ref="xxf:instance('my-error-instance')//submission[1]/#name" value="event('target')"/>
<xf:setvalue ref="xxf:instance('my-error-instance')//submission[#name=event('target')]/status-code" value="event('response-status-code')"/>
<xf:setvalue ref="xxf:instance('my-error-instance')//submission[#name=event('target')]/uri" value="event('resource-uri')"/>
<xf:setvalue ref="instance('my-error-instance')//submission[#name=event('target')]/date" value="event('response-headers')[lower-case(name) = 'date']/value"/>
</xf:action>
</xf:model>
Took attention to two conditions (in insert and first setvalue). Because of them model save only last error of one submission. If you want for some reason history, you can delete them.

Orbeon : One submission after another

In my form file I have a submission load-data-submission which fetches some data from database, it is called on xforms-ready :
<xf:model>
...
<xf:action ev:event="xforms-ready" ev:observer="fr-form-model" if="true()">
<xf:send submission="load-data-submission"/>
</xf:action>
...
</xf:model>
Now, I have an XBL controll which is used in this very same form. There is another submission which also fetches data etc, let's call it rest-submission. Now, I would like the rest-submission (the one inside XBL) to be called right after my load-data-submission (the one inside form file) would fetch data.
How would I do that ? I've tried put inside XBL
<xf:action ev:observer="load-data-submission" ev:event="xforms-submit-done">
<xf:send submission="rest-submission"/>
</xf:action>
with no luck.
Thanks in advance.
To avoid id clashes and enable encapsulation, XBL defines a new lexical scope for ids and a new XPath context. So if from inside the XBL you refer to id load-data-submission, this refers to a load-data-submission defined within the XBL, which is most likely non-existent in your case. To reference ids outside of the XBL, you need to change the scope with the xxbl:scope="outer" attribute. The following example illustrates how to do that:
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:example="http://example.com/">
<xh:head>
<xf:model>
<xf:submission
id="get-states"
method="get"
resource="/xforms-sandbox/service/zip-states"
replace="instance"
instance="states"/>
<xf:instance id="states">
<empty/>
</xf:instance>
</xf:model>
<xbl:xbl>
<xbl:binding element="example|simple">
<xbl:implementation>
<xf:model id="simple-model">
<xf:instance>
<internal/>
</xf:instance>
</xf:model>
</xbl:implementation>
<xbl:template>
<xf:group>
<xf:message ev:observer="get-states"
ev:event="xforms-submit-done"
xxbl:scope="outer"
value="'Got event'"/>
</xf:group>
</xbl:template>
</xbl:binding>
</xbl:xbl>
</xh:head>
<xh:body>
<example:simple/>
<xf:trigger>
<xf:label>Get states</xf:label>
<xf:send submission="get-states" ev:event="DOMActivate"/>
</xf:trigger>
</xh:body>
</xh:html>

Passing parameters to XBL in Orbeon

I've created these two simple files , view.xhtml :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms">
<head>
<title>Test</title>
<xf:model>
<!-- Instance that contains all the books -->
<xf:instance id="people-instance">
<people xmlns="">
<person>
<test/>
</person>
</people>
</xf:instance>
<xf:bind id="test-bind" name="test" ref="person/test"/>
</xf:model>
</head>
<body>
<xf:input id="test-control" bind="test-bind">
<xf:label>THIS</xf:label>
</xf:input>
<fr:my-name test="'test'">
</fr:my-name>
</body>
And my-name.xbl :
<xbl:xbl xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
<xbl:binding element="fr|my-name" id="fr-my-name" xxbl:mode="lhha binding value">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder" xmlns:xf="http://www.w3.org/2002/xforms">
<templates>
<view>
<fr:my-name id="" appearance="minimal" xmlns="" test="" >
</fr:my-name>
</view>
</templates>
<xf:input ref="#test">
<xf:label lang="en">Resource URI</xf:label>
</xf:input>
</metadata>
<xbl:template>
<!-- Local model and instance -->
<xf:var name="test-avt" xbl:attr="xbl:text=test" xxbl:scope="outer"/>
<xf:var name="test" xbl:attr="xbl:text=test" >
<xf:action ev:event="xforms-enabled xforms-value-changed">
<xf:setvalue ref="instance('test')" value="$test"/>
</xf:action>
<xxf:sequence value="xxf:evaluate-avt($test-avt)" xxbl:scope="outer"/>
</xf:var>
<xf:model>
<xf:instance id="test"><value/></xf:instance>
<xf:instance><value/></xf:instance>
<xf:submission id="save-submission" ref="instance('test')"
action="/exist/rest/db/orbeon/my-name/person.xml"
method="put" replace="none">
<xf:message ev:event="xforms-submit-error" level="modal">An error occurred while saving!</xf:message>
</xf:submission>
</xf:model>
<xf:input class="xforms-disabled" ref="xxf:instance('people-instance')//*[name() = saxon:evaluate($test)]" >
<xf:label>Your name</xf:label>
<xf:send ev:event="xforms-value-changed" submission="save-submission"/>
</xf:input>
</xbl:template>
</xbl:binding>
Now I would like pass parameters from my view.xhtml to XBL so when user inserts something in xf:input id='test-control' it would cause that the text will be saved in database.
The problem is, instead of what user actually inserted in my database I have :
<value>'test'</value>
instead of expected, f.e. if I insert 123
<value>123</value>
Anyone has any idea why my code doesn't work and how to fix this ?
Here is an example which works. I put both files together to make it easier to try.
A few things I changed:
If your test attribute is in fact an AVT, it shouldn't have quotes around it. So you have for example test="foo{42}" which evaluates to foo42, which, if I understand well, is the name of the XML element you want to observe.
You probably don't want saxon:evaluate($test): the AVT is already evaluated and the result available in the variable $test. There is no point evaluating the result as an XPath expression again.
The 2nd var must not have xbl:attr="xbl:text=test"
Optional: I used xxf:binding-context('fr-my-name')/root() instead of xxf:instance(), but xxf:instance() will work too (although its usage is not recommended).
Optional: I moved the XBL model under xbl:implementation. It makes it clearer that this is not dependent on the template.

Refer to an outer instance from an XBL component in Orbeon

I am making my own component and within it I want to set value of an outer instance. For example, my main form has:
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance">
<form>
<section-1>
<myControl/>
</section-1>
</form>
</xf:instance>
...
and inside myControl.xbl I have:
<xf:setvalue
model="fr-form-model"
ref="instance('fr-form-instance')/form/section-1/myControl"
value="'myValue'" />
but unfortunately it doesn't see fr-form-model ("Reference to non-existing model id: fr-form-model") which is understandable, because the component is encapsulated and cannot see outer elements. How can I refer to the outer instance?
You can write to the control binding with xxf:binding() (see also gist):
<xh:html
xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner">
<xh:head>
<xf:model>
<xf:instance>
<value/>
</xf:instance>
</xf:model>
<xbl:xbl xmlns:xbl="http://www.w3.org/ns/xbl" xmlns:xxbl="http://orbeon.org/oxf/xml/xbl">
<xbl:binding id="fr-gaga" element="fr|gaga" xxbl:mode="binding">
<xbl:template>
<xf:trigger>
<xf:label>Set value</xf:label>
<xf:setvalue event="DOMActivate" ref="xxf:binding('fr-gaga')" value="42"/>
</xf:trigger>
</xbl:template>
</xbl:binding>
</xbl:xbl>
</xh:head>
<xh:body>
<fr:gaga ref="instance()"/>
<xf:output value="instance()"/>
</xh:body>
</xh:html>
Otherwise, the quick and dirty way is to use the xxf:instance() function instead. It has visibility through the boundaries of XBL components. But we don't recommend it as it breaks encapsulation.
See also this forum answer.

Custom control: dropdown values from XML file

Here is my custom control:
<?xml version="1.0" encoding="UTF-8"?>
<xbl:xbl xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:xbl="http://www.w3.org/ns/xbl">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder">
<display-name lang="en">Custom Controls</display-name>
</metadata>
<xbl:binding id="fb-input-country-selector" element="xforms|country-selector">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder">
<display-name lang="en">Country Selector</display-name>
<icon lang="en">
<small-icon>/forms/orbeon/builder/images/dropdown.png</small-icon>
<large-icon>/forms/orbeon/builder/images/dropdown.png</large-icon>
</icon>
<datatype>xforms:string</datatype>
<template>
<xforms:select1 id="" appearance="minimal" ref="" xmlns="">
<xforms:label ref=""/>
<xforms:hint ref=""/>
<xforms:help ref=""/>
<xforms:alert ref="$fr-resources/detail/labels/alert"/>
<xforms:item>
<xforms:label>[Select...]</xforms:label>
<xforms:value/>
</xforms:item>
<xforms:itemset nodeset="doc('oxf:/apps/xforms-controls/services/countries.xml')/countries/country">
<xforms:label ref="name"/>
<xforms:value ref="us-code"/>
</xforms:itemset>
</xforms:select1>
</template>
</metadata>
</xbl:binding>
</xbl:xbl>
The problem is that the data items are not grabbed from the XML, but if I introduce the template itself in the form structure, it works.
Anyone have any ideea?
Creating XBL components is tricky. At least the first time you do it. A few things:
To avoid confusions, I recommend you define components in your own namespace. In the example below, I used xmlns:my="http://www.example.com/".
The content of fb:template is how using the component looks like, not its implementation. So, it should look like:
<fb:template>
<my:country-selector>
<xforms:label ref=""/>
<xforms:hint ref=""/>
<xforms:help ref=""/>
<xforms:alert ref=""/>
</my:country-selector>
</fb:template>
The implementation is inside xbl:template.
So the component can be found at runtime, you need to place it in a directory xbl/my/country-selector/country-selector.xbl. The my part of the directory is mapped to the namespace by you adding the following property in your properties-local.xml:
<property as="xs:string" name="oxf.xforms.xbl.mapping.my"
value="http://www.example.com/"/>
(Often, we use the same name for the directory and the prefix, but they don't need to be the same. E.g. the fr:* components are in a directory called orbeon.)
So Form Builder shows your component in the sidebar, you need to add a property like:
<property as="xs:string" name="oxf.fb.toolbox.group.other.uri.*.*"
value="oxf:/xbl/my/country-selector/country-selector.xbl"/>
And here is the full source for country-selector.xbl:
<xbl:xbl xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:my="http://www.example.com/"
xmlns:saxon="http://saxon.sf.net/"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder"
xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:xxbl="http://orbeon.org/oxf/xml/xbl">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder">
<display-name lang="en">Custom Controls</display-name>
</metadata>
<xbl:binding id="my-country-selector" element="my|country-selector" xxbl:mode="lhha binding value">
<fb:metadata>
<fb:display-name lang="en">Country Selector</fb:display-name>
<fb:icon lang="en">
<fb:small-icon>/forms/orbeon/builder/images/dropdown.png</fb:small-icon>
<fb:large-icon>/forms/orbeon/builder/images/dropdown.png</fb:large-icon>
</fb:icon>
<fb:datatype>xforms:string</fb:datatype>
<fb:template>
<my:country-selector>
<xforms:label ref=""/>
<xforms:hint ref=""/>
<xforms:help ref=""/>
<xforms:alert ref=""/>
</my:country-selector>
</fb:template>
</fb:metadata>
<xbl:template>
<xforms:select1 appearance="minimal" ref="xxf:binding('my-country-selector')">
<xforms:item>
<xforms:label>[Select...]</xforms:label>
<xforms:value/>
</xforms:item>
<xforms:itemset nodeset="doc('oxf:/forms/orbeon/controls/service/countries.xml')/countries/country">
<xforms:label ref="name"/>
<xforms:value ref="us-code"/>
</xforms:itemset>
</xforms:select1>
</xbl:template>
</xbl:binding>
</xbl:xbl>

Resources