eXist-db通过controller.xql(URL映射)向模板传递参数

eXist-db passing parameters to templates through controller.xql (URL mapping)

我使用 eXist 的默认安装 controller.xqlview.xq.

使用 eXist-db 4.2.1 和 Xquery 3.1

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

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

而且他们的待遇是一样的...

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

 [...]
 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模板and/or在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:...调用depend on the same parameter provided<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.

'expected cardinality'提示参数没有进入函数?

编辑:

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

 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>

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

(您引用的答案有误 - 我现在已更正。抱歉,感谢您的全面测试和清晰的问题!)