eXist-db 通过 controller.xql(URL 映射)向模板传递参数 [英] eXist-db passing parameters to templates through controller.xql (URL mapping)

查看:29
本文介绍了eXist-db 通过 controller.xql(URL 映射)向模板传递参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有一个 document.html,我将任何传入的 url 以 /doc/some-requested-doc-id 结构传递给它,以生成动态-基于 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/ 并清理预期的 some-requested-doc-id 使用传递给参数的 functionname="currentdoc":

<代码> [...]else if (starts-with($exist:path, "/doc/")) then(:去掉任何扩展名并将全局变量重命名为 .xml :)<调度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 url="{$exist:controller}/modules/view.xql"/></查看></调度>[...]

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

 

<div data-template="document:title-bar"/><div class="col-sm-12"><div class="col-md-2 侧边栏"><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 class="col-md-10 文档视图"><div data-template="document:doc-xsl-docview"/>

5 data-template="document:... 调用 依赖于 提供的相同参数,例如

调用:

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

返回 $x};

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

 

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

 参数 3 的实际基数与函数签名中声明的基数:文档:标题栏($node 作为节点(),$model 作为地图,$currentdoc as xs:string) item()*.预期基数:正好 1,得到 0.

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

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

 声明函数 document:title-bar($currentdoc 作为 xs:string,$node 作为 node(),$model as map(*))

我收到一个不同的错误:

 提供的函数参数 2:文档:标题栏($currentdoc as xs:string,$node 作为 node(), $model 作为 map) item()* 没有匹配所需的类型.必需的类型节点(),得到了地图.`

非常感谢.

解决方案

指令需要移到第二个 指令——以便 modules/view.xql 可以访问参数.此控制器片段的更正版本是:

else if (starts-with($exist:path, "/doc/")) then(:去掉任何扩展名并将全局变量重命名为 .xml :)<调度xmlns="http://exist.sourceforge.net/NS/exist"><forward url="{$exist:controller}/document.html"/><查看><forward url="{$exist:controller}/modules/view.xql"><add-parameter name="currentdoc" value="{concat(functx:substring-before-match($exist:resource,'[.]'),'.xml')}"/></转发></查看></调度>

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

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

I am working with eXist-db 4.2.1 and Xquery 3.1 using the eXist's default installation of controller.xql and view.xq.

I have a document.html to which I pass any incoming url structured with /doc/some-requested-doc-id at the end to produce a dynamically-created page based on some-requested-doc-id.

So, the incoming url can be either http://localhost:8080/exist/apps/deheresi/doc/MS609-0001 or http://localhost:8080/exist/apps/deheresi/doc/MS609-0001.xml

and they are treated the same...

In the file controller.xql I have a condition for matching this request, which identifies /doc/ and cleans up the expected some-requested-doc-id using a function which is passed to parameter 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>
 [...]

The requested .html file is as follows, which itself calls other HTML templates and/or dynamically created content in 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>

The 5 data-template="document:... calls depend on the same parameter provided by <add-parameter>, for example <div data-template="document:title-bar"/> calls:

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
};   

Even if I hard-code the parameter in the module controller.xql:

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

I still get the same error, which doesn't happen if I hard code the parameter in the template call:

 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.

The 'expected cardinality' suggests that the parameter is not coming into the function?

EDIT:

If I change the order of parameters in the function above to

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

I get a different error:

  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. `

Many thanks in advance.

解决方案

The <add-parameter> directive needs to be moved to the 2nd <forward> directive—so that modules/view.xql has access to the parameter. The corrected version of this fragment of your controller is:

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>

The templating documentation also shows this - see the 2nd code sample under the "Set up" section here: https://exist-db.org/exist/apps/doc/templating#D3.35.

(There was a mistake in the answer you referenced - which I have now corrected. Apologies, and thanks for your thorough testing and well-articulated questions!)

这篇关于eXist-db 通过 controller.xql(URL 映射)向模板传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆