Estensione di application.cfc in una sottodirectory
-
08-07-2019 - |
Domanda
Ho i seguenti due file e vorrei che il secondo estendesse il primo:
- wwwroot \ sito \ Application.cfc
- wwwroot \ sito \ dir \ Application.cfc
Tuttavia, quando vado a dichiarare il componente per il secondo file, non sono sicuro di cosa inserire l'attributo extends. Il mio problema è che diversi siti di sviluppo (con un repository SVN condiviso) stanno eseguendo la stessa istanza di ColdFusion , quindi non posso semplicemente creare una mappatura nell'amministratore CF in questo modo:
<cfcomponent extends="site.application">
Tuttavia, a ColdFusion non piace:
<cfcomponent extends="..application">
o qualsiasi input dinamico come:
<cfcomponent extends="#expandpath('..').#application">
La creazione di una mappatura di runtime ( come qui ) no sembra possibile neanche. La sua creazione in application.cfc di base è inutile perché quel codice non è stato ancora eseguito al momento della dichiarazione del cfc ereditario; e non riesco a creare il mapping prima che il componente ereditario sia definito perché non esiste ancora un'applicazione a cui collegarlo.
Esiste un modo in cui posso fare riferimento alla directory principale per realizzare le mie estensioni?
Modifica per chiarire: la soluzione ApplicationProxy non funziona a causa del testo in grassetto sopra. Al momento, come soluzione alternativa, non stiamo semplicemente controllando il file \ dir \ application.cfc in SVN in modo che ogni sviluppatore possa mantenere una versione che estende il proprio root.c.cc dell'applicazione. Ovviamente, questo non è l'ideale.
Soluzione
Il seguente codice funziona per me. Una cosa che ho notato è che application.cfc sembra essere memorizzato nella cache, quindi le modifiche all'applicazione padre cfc potrebbero non essere riflesse. Ho risolto il problema facendo una banale modifica all'applicazione figlio cfc.
<cfcomponent output="false">
<cfset variables.higherPath = ReReplace(GetMetaData(this).name,"\.[^\.]+\.[^\.]+<*>quot;,"") />
<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>
Altri suggerimenti
Sean Corfield ha una voce del blog che spiega come estendere una radice Application.cfc .
Di seguito sono riportate le informazioni pertinenti copiate da quella voce.
Ecco il tuo CFC root /Application.cfc:
<cfcomponent>
<cfset this.name = "cf7app" />
<cfset this.sessionmanagement = true />
</cfcomponent>
Ecco il tuo proxy CFC /ApplicationProxy.cfc:
<cfcomponent extends="Application">
</cfcomponent>
È completamente vuoto e serve semplicemente a creare un alias per il tuo root /Application.cfc. Ecco la tua sottodirectory 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>
La radice di ogni singolo sito dovrebbe avere la sua app principale:
/site1/Application.cfc
/site2/Application.cfc
/site3/Application.cfc
Tutte queste applicazioni sono singole app separate con nulla condiviso tra loro.
Se uno di questi singoli siti deve avere delle sotto-applicazioni, dovrebbe esserci ApplicationProxy.cfc al di fuori del Master,
e.g.
/site1/ApplicationProxy.cfc
/site2/ApplicationProxy.cfc
Quindi, per ogni sub-applicazione hai quella che estende il proxy:
e.g.
/site1/subA/Application.cfc
/site1/subB/Application.cfc
/site2/subA/Application.cfc
So che questo è un vecchio argomento, ma ho trovato un modo per farlo (che sembra funzionare nei miei test) senza usare i mapping dell'amministratore CF.
Puoi farlo aggiungendo un mapping per applicazione nel tuo Application.cfc figlio usando un percorso relativo espanso:
<cfcomponent extends="cms.Application" output="false">
<cfset this.mappings["/cms"] = expandPath(getDirectoryFromPath(getCurrentTemplatePath()) & "../../../../")>
<cflog text="#getMetadata(this).extends.path#">
</cfcomponent>
Sì, sembra un po 'confuso, ma sembra funzionare.