我们已经开始使用Orbeon Form Builder来创建表单,但是我们希望能够使用源代码控制(Git)来管理我们创建的表单。因此,我们希望将表单存储在文件系统而不是数据库中(作为旁注,表单中的数据将单独处理)。
我已经看到/这样做的方法是为它创建一个(自定义)持久层(http://doc.orbeon.com/configuration/properties/persistence.html http://doc.orbeon.com/form-runner/api/persistence/index.html)。
是否有记录/可用的方法轻松完成此操作而无需重新发明轮子(Orbeon 4.2 Form Builder makes /crud/orbeon/builder/form/form.xhtml request to the custom persistence layer)?
答案 0 :(得分:0)
实现这一目标的一种方法是利用资源持久层。目前,资源持久层仅支持读取操作,并且需要improved to also support write operations。这样,您就可以使用表单生成器创建,编辑和发布表单。这会将文件写入磁盘,然后您可以单独使用Git添加/ commit / push。
(持久层也可以为你做Git上的那些操作,但是我想大多数Git用户都想要比全自动系统更多的控制。)
答案 1 :(得分:0)
完成后,我们已经实施了这个目标。
我们正在使用Git存储库来存储我们对Orbeon安装所做的更改(在新的Orbeon安装上,我们将该文件夹初始化为git存储库,将我们的存储库添加为远程存储库,然后拉入存储库)。
对于开发实例,我们使用默认的eXist数据库,因此开发人员必须在首次启动时或在其他人对表单进行更改时手动将表单复制到表单构建器中。
当开发人员准备好提交到存储库时,他们可以使用Node.js脚本(下面)提取表单(草稿版本和发布版本),使用CRUD API抓取XML并将其存储在资源持久层的正确位置。
在非开发实例中,使用资源持久层而不是eXist,因此Orbeon从文件系统(WEB-INF/resource/forms/<APP_NAME>/<FORM_NAME>/form/form.xhtml
)中获取表单。我们没有使用Orbeon存储任何数据(这全部由其他服务处理)。
目前这对我们来说效果还不错 - 如果有两个人在同一个表单上工作,那么合并会变得非常艰巨,因为形式xml不是......最简单。开发/非开发环境的差异并存储在properties-local-dev.xml
和properties-local-prod.xml
中(通过更改运行模式选择(WEB-INF/web.xml
)
Node.js getForm.js
脚本
#!/usr/bin/env node
var get = require('get');
var mkdirp = require('mkdirp');
var fs = require('fs');
var path = require('path');
if (process.argv.length !== 6) {
console.error("usage: getForm.sh <url> <application> <form> <editFormId>");
console.error("Gets the latest version of a form from Orbeon");
console.error("<editFormId> is the id of the latest version of the form in form ");
console.error(" eg, the last part of the edit form url");
console.error(" http://localhost/orbeon/fr/orbeon/builder/edit/<editFormId>");
console.error("eg: getForm.sh http://127.0.0.1:8080/orbeon APP FORM 72e300fe7d8f2d2604f31b690760865a23dbeaed");
return 1;
}
// Check for WEB-INF folder so we know we are running from the right folder
try {
fs.accessSync('WEB-INF', fs.R_OK);
} catch (err) {
console.error('Problem finding WEB-INF folder. Need to run from base of '
+ 'Orbeon folder', err.stack);
return 2;
}
// Create folders if required
var publishedFolder = path.join('WEB-INF/resources/forms/', process.argv[3],
process.argv[4], 'form');
var draftFolder = path.join('src/forms/', process.argv[3]);
var folders = [publishedFolder, draftFolder];
var f;
for (f in folders) {
try {
fs.accessSync(folders[f], fs.R_OK);
} catch (err) {
if (err.code === 'ENOENT') {
// Try creating the folder
try {
mkdirp.sync(folders[f]);
} catch (err) {
console.error("Error creating folder", folders[f], err.stack);
return 3;
}
} else {
console.error("Error checking access permissions to folder", folders[f], err.stack);
return 4;
}
}
}
try {
// Add http to url if it doesn't already contain it
if (!process.argv[2].match(/^https?:\/\//)) {
process.argv[2] = 'http://' + process.argv[2];
}
var publishedURL = process.argv[2] + '/fr/service/persistence/'
+ 'crud/' + process.argv[3] + '/' + process.argv[4] + '/form/form.xhtml';
var publishedFile = path.join(publishedFolder, 'form.xhtml');
console.log('Getting the latest published version of the form from '
+ publishedURL + ' and saving it to', publishedFile);
var published = get(publishedURL);
// Write to file
published.toDisk(publishedFile, function(err, filename) {
if (err) {
console.error('Error storing the latest published version of the form',
publishedURL, ' > ', publishedFile, err.stack);
}
return 5;
});
} catch (err) {
console.error('Error getting the latest published version of the form',
publishedURL, ' > ', publishedFile, err.stack);
return 6;
}
try {
var draftURL = process.argv[2] + '/fr/service/persistence/crud/'
+ 'orbeon/builder/data/' + process.argv[5] + '/data.xml';
console.log(draftURL);
var draftFile = path.join(draftFolder,
process.argv[4] + '.xhtml');
console.log('Getting the latest draft version of the form from '
+ draftURL + ' and saving it to', draftFile);
var draft = get(draftURL);
// Write to file
draft.toDisk(draftFile, function(err, filename) {
if (err) {
console.error('Error storing the latest draft version of the form',
draftURL, ' > ', draftFile, err.stack);
}
return 7;
});
} catch (err) {
console.error('Error getting the latest draft version of the form',
draftURL, ' > ', draftFile, err.stack);
return 8;
}
启用对CRUD API的访问
<property
as="xs:string"
processor-name="oxf:page-flow"
name="page-public-methods"
value="GET HEAD POST PUT DELETE"/>
<property
as="xs:string"
processor-name="oxf:page-flow"
name="service-public-methods"
value="GET HEAD POST PUT DELETE"/>