我有以下两个文件,并希望第二个文件扩展第一个:
但是,当我为第二个文件声明组件时,我不确定要在extends属性中放入什么。 我的问题是几个开发站点(有一个共享的SVN存储库)正在运行ColdFusion的同一个实例,所以我不能像这样在CF管理员中创建一个映射:
<cfcomponent extends="site.application">
但是,ColdFusion不喜欢:
<cfcomponent extends="..application">
或任何动态输入,如:
<cfcomponent extends="#expandpath('..').#application">
创建运行时映射(like here)似乎也不可行。在基础application.cfc中创建它是没用的,因为在声明继承cfc时该代码尚未执行;并且我无法在定义继承组件之前创建映射,因为还没有应用程序将其附加到。
有什么方法可以引用父目录来完成我的扩展吗?
编辑以澄清:由于上面的粗体文本,ApplicationProxy解决方案不起作用。现在,作为一种解决方法,我们只是不将\ dir \ application.cfc检查到SVN,以便每个开发人员都可以保留一个扩展他/她自己的根application.cfc的版本。显然,这并不理想。
答案 0 :(得分:16)
Sean Corfield有a blog entry explaining how to extend a root Application.cfc。
以下是从该条目复制的相关信息。
这是您的根CFC /Application.cfc:
<cfcomponent>
<cfset this.name = "cf7app" />
<cfset this.sessionmanagement = true />
</cfcomponent>
这是您的代理CFC /ApplicationProxy.cfc:
<cfcomponent extends="Application">
</cfcomponent>
它完全是空的,仅用于为您的根/Application.cfc创建别名。这是您的子目录CFC /app/Application.cfc:
<cfcomponent extends="ApplicationProxy">
<cffunction name="onSessionStart">
<cfoutput><p>app.Application.onSessionStart()</p></cfoutput>
<cfset session.counter = 0 />
</cffunction>
<cffunction name="onRequestStart">
<cfoutput><p>app.Application.onRequestStart()</p></cfoutput>
<cfdump label="application" var="#application#"/>
</cffunction>
</cfcomponent>
每个个别网站的根目录应该有自己的主应用程序:
/site1/Application.cfc
/site2/Application.cfc
/site3/Application.cfc
所有这些应用程序都是单独的应用程序,它们之间没有任何共享。
如果这些单独的站点中的任何一个需要有子应用程序,那么应该有MasterProxy.cfc,
e.g.
/site1/ApplicationProxy.cfc
/site2/ApplicationProxy.cfc
然后,对于每个子应用程序,您都拥有扩展代理的那个:
e.g.
/site1/subA/Application.cfc
/site1/subB/Application.cfc
/site2/subA/Application.cfc
答案 1 :(得分:4)
以下代码对我有用。我注意到的一件事是application.cfc似乎被缓存了,因此可能不会反映对父应用程序cfc的更改。我通过对子应用程序cfc进行微不足道的更改来解决这个问题。
<cfcomponent output="false">
<cfset variables.higherPath = ReReplace(GetMetaData(this).name,"\.[^\.]+\.[^\.]+$","") />
<cfset variables.extendApp = CreateObject("component", "#variables.higherPath#.Application") />
<cfloop item="variables.key" collection="#variables.extendApp#">
<cfif IsCustomFunction(variables.extendApp[variables.key])>
<cfset super[variables.key] = variables.extendApp[variables.key]>
<cfelse>
<cfset this[variables.key] = variables.extendApp[variables.key] >
</cfif>
</cfloop>
<cffunction name="onApplicationStart" output="false">
<cfset super.onApplicationStart() />
</cffunction>
答案 2 :(得分:3)
我知道这是一个古老的主题,但我找到了一种方法(在我的测试中似乎有效),而不使用CF管理员映射。
您可以使用扩展的相对路径在您的子Application.cfc中添加每个应用程序映射来执行此操作:
<cfcomponent extends="cms.Application" output="false">
<cfset this.mappings["/cms"] = expandPath(getDirectoryFromPath(getCurrentTemplatePath()) & "../../../../")>
<cflog text="#getMetadata(this).extends.path#">
</cfcomponent>
是的,感觉不太苛刻,但似乎有效。
答案 3 :(得分:0)
爱德华等人,我在下面的帖子中提到了您的评论。见https://gregoryalexander.com/blog/2021/1/30/Extending-Applicationcfcs-using-mappings-and-proxies
您绝对可以使用映射扩展 cfc。我必须自己做。
我在 ColdFusion 中不得不处理的最令人沮丧的事情之一是尝试创建一个对公众开放的外部应用程序,并且必须使用子文件夹中的应用程序保护该站点的一部分并扩展来自基本 application.cfc 的逻辑。我将向您介绍当前开发人员用来解决此问题的方法,并向您展示如何在可能存在使用虚拟目录的托管服务提供商时额外使用映射。
这是一篇很长的文章,如果您想跳转到简明摘要,请向下滚动到本页底部。
多年前,当我第一次尝试执行此操作时,无论尝试什么,我都收到以下消息:“找不到 ColdFusion 组件或接口 xxx'。简而言之,使用这种方法的问题是发现根文件夹和子文件夹同名,即Application.cfc,ColdFusion无法正确识别扩展哪个组件。最后,经过一番认真的调查,有人想出了创建一个驻留的proxy.cfc的想法在与根 Application.cfc 相同的根目录中,子文件夹中的 Application.cfc 扩展了一个空的 proxy.cfc,它扩展了根 cfc,如下所示:
根目录:Application.cfc 这个根 Application.cfc 没有扩展任何东西
也在根目录下:Proxy.cfc Proxy.cfc 有以下代码,它本质上是空的。 Proxy.cfc 所做的唯一一件事就是扩展同一目录中的 Application.cfc:
子目录,例如名为 admin 的文件夹。 该子目录有另一个 Application.cfc。假设该组件负责保护应用程序并具有登录逻辑以及调试设置等。这个 Application.cfc 将扩展 Proxy.cfc 以获得根目录下 Application.cfc 的方法和属性,如下所示:
这种方法真是天赐之物,并且在博客上得到了大量讨论。 Ben Nadel 发表了许多非常有用的帖子,我将在本文底部分享。
除非您在托管域或使用虚拟目录的服务器上,否则这非常有效。在这种情况下,我们在我们开始的同一条船上。现在我们又回到了“找不到 ColdFusion 组件或接口 xxx'地狱!
虽然这个棘手的问题有一个解决方案,但我们还需要使用映射!
不能使用映射来扩展组件是一个常见的误称。我不太确定这种误解最初来自哪里,但已经证明这不是真的。有时我们必须使用映射来解决一些烦人的问题,比如这里。
此特定站点由 hostek.com 托管。他们是一家很好的公司,但由于目录结构的原因,我的站点所在的服务器有一些特性。在这里,当我使用 Proxy.cfc 方法将逻辑从基本 Application.cfc 扩展到 admin 文件夹中的 Application.cfc 时,我收到可怕的“找不到...组件”错误。当我第一次看到它时,我很沮丧,再次想到它,所以我转向了 ColdFusion CFC 映射。映射告诉 ColdFusion 在哪里可以找到文件以及文件关系是什么。
让我们回顾一下刚刚讨论的 CFC 结构。例如,想象以下目录结构:
根目录:即www.gregoryalexander.com/ 子目录:www.gregoryalexander.com/admin/
如前所述,我们在根目录中有 Application.cfc 和 Proxy.cfc,在 'admin' 子目录中有 Application.cfc。 Proxy.cfc 扩展了Application.cfc,也在根目录下,子目录(admin)中的Application.cfc 扩展了根目录下的Proxy.cfc。
根目录:包含 Application.cfc 和 Proxy.cfc(扩展根 Application.cfc)。 子目录:Application.cfc(扩展 Proxy.cfc)。
现在我们还需要在根 Application.cfc 中添加以下映射。此映射逻辑应靠近根 Application.cfc 的顶部,并且不应位于任何 Application.cfc 事件处理程序(onApplicationStart、onApplicationRequest 等)内。此映射代码不需要位于根 Application.cfc 之外的任何其他位置:
我使用 rootCfc 来标识根目录中的 Application.cfc,而 adminCfc 适用于 admin 目录中的应用程序。这些变量可以任意命名。请注意,adminCfc 映射末尾的“/admin”字符串指向“admin”文件夹,这是一个子目录。
现在我们在根 Application.cfc 中有映射,我们需要将它们应用到位于子目录中的 Application.cfc 中的 extends 语句。在 /admin/Application.cfc 模板中使用:
/admin/Application.cfc
当然,rootCfc是告诉子目录下的Application.cfc去根目录下寻找Proxy.cfc模板。与其他“extend”语句一样,您无需在 Proxy 末尾指定“.cfc”。
您无需在根 Proxy.cfc 或 Application.cfc 模板中使用此“扩展”映射。他们已经可以找到对方了,因为他们都在同一个根目录下。
/Proxy.cfc
总结 为了绝对清楚: 根应用程序.cfc 包含映射逻辑。具有根目录和子目录的映射。 不使用“扩展”语句
根代理.cfm 一个简单的 'extends="Administrator" 工作。 没有映射逻辑。
子目录Application.cfc extends 语句必须是文件夹的映射变量名称(rootCfc),一个点(.),最后是不带 .cfc 前缀的 Proxy.cfc 模板名称(Proxy)
我很抱歉这么冗长。写这篇文章的时候我很恼火——但我在尝试解决这个问题时并没有那么恼火!
保重!