eXistdb通过controller.xql(URL映射)将参数传递给模板



我使用eXist的默认安装controller.xqlview.xq来处理eXist db 4.2.1和Xquery 3.1。

我有一个document.html,我将任何以/doc/some-requested-doc-id结尾构建的传入url传递给它,以生成基于some-requested-doc-id的动态创建页面。

因此,传入的url可以是http://localhost:8080/exist/apps/deheresi/doc/MS609-0001http://localhost:8080/exist/apps/deheresi/doc/MS609-0001.xml

他们受到同样的待遇。。。

在文件controller.xql中,我有一个匹配此请求的条件,该条件标识/doc/,并使用传递给参数name="currentdoc":的函数清除预期的some-requested-doc-id

[...]
else if (starts-with($exist:path, "/doc/")) then
(: strip out any extensions and rename global variable as .xml:)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/document.html">
<add-parameter name="currentdoc" 
value="{concat(functx:substring-before-match($exist:resource,'[.]'),'.xml')}"/>
</forward>
<view>
<forward url="{$exist:controller}/modules/view.xql"/>
</view>
</dispatch>
[...]

请求的.html文件如下,它本身调用其他html模板和/或XQuery:中动态创建的内容

<div data-template="templates:surround" data-template-with="templates/site_wrapper.html" data-template-at="content">
<div data-template="document:title-bar"/>
<div class="col-sm-12">
<div class="col-md-2 sidebar">
<div data-template="document:doc-sidebar-sub1"/>
<div data-template="document:doc-sidebar-sub2"/>
<div data-template="document:doc-sidebar-sub3"/>
<div data-template="document:doc-sidebar-sub4"/>
</div>
<div class="col-md-10 document-view">
<div data-template="document:doc-xsl-docview"/>
</div>
</div>
</div>

5个data-template="document:...调用依赖于<add-parameter>提供的相同参数,例如<div data-template="document:title-bar"/>调用:

declare function document:title-bar( 
$node as node(), 
$model as map(*), 
$currentdoc as xs:string)
{   
let $persid := person:person-name(data(doc(concat($globalvar:URIdata,$currentdoc))/tei:TEI/tei:text//tei:persName[@role="dep"]/@nymRef)) 
let $doctypeen := data(doc(concat($globalvar:URIdata,$currentdoc))/tei:TEI/tei:text//tei:div[@type="doc_type"]/@subtype)
let $x :=
<div class="col-md-12 document-title">
<h2><span class="en">{$doctypeen}: </span><span class="fr">{document:doc-type-french($doctypeen)} : </span>{$persid}</h2>
</div>
return $x
};   

即使我在模块controller.xql:中对参数进行硬编码

<add-parameter name="currentdoc" value="MS609-00001.xml"/>

我仍然会得到同样的错误,如果我在模板调用中对参数进行硬编码,则不会发生这种错误:

The actual cardinality for parameter 3 does not match the 
cardinality declared in the function's signature: 
document:title-bar($node as node(), $model as map, 
$currentdoc as xs:string) item()*. 
Expected cardinality: exactly one, got 0.

"预期基数"表明参数没有进入函数?

编辑:

如果我将上述函数中的参数顺序更改为

declare function document:title-bar( 
$currentdoc as xs:string, 
$node as node(), 
$model as map(*))

我得到一个不同的错误:

Supplied argument 2 of function: 
document:title-bar($currentdoc as xs:string, 
$node as node(), $model as map) item()* does not 
match required type. Required type node(), got map. `

非常感谢。

<add-parameter>指令需要移动到第二个<forward>指令,以便modules/view.xql可以访问该参数。你的控制器的这个片段的修正版本是:

else if (starts-with($exist:path, "/doc/")) then
(: strip out any extensions and rename global variable as .xml:)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/document.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<add-parameter name="currentdoc" value="{concat(functx:substring-before-match($exist:resource,'[.]'),'.xml')}"/>
</forward>
</view>
</dispatch>

模板文档也显示了这一点——请参阅此处"设置"部分下的第二个代码示例:https://exist-db.org/exist/apps/doc/templating#D3.35.

(你提到的答案有一个错误,我现在已经纠正了。很抱歉,感谢你的全面测试和清晰的问题!(

相关内容

最新更新