У меня есть два следующих файла, и я бы хотел, чтобы второй расширил первый:
Однако, когда я собираюсь объявить компонент для второго файла, я не уверен, что добавить в атрибут extends. Моя проблема в том, что несколько сайтов разработчиков (с общим репозиторием SVN) работают на одном экземпляре ColdFusion., поэтому я не могу просто создать отображение в админке CF вот так:
<cfcomponent extends = "site.application">
Однако ColdFusion не любит:
<cfcomponent extends = "..application">
или любой динамический ввод, например:
<cfcomponent extends = "#expandpath('..').#application">
Создание отображения времени выполнения (как здесь) также не представляется возможным. Создавать его в базовом application.cfc бесполезно, потому что этот код еще не выполнен к моменту объявления наследующего cfc; и я не могу создать сопоставление до того, как будет определен наследующий компонент, потому что еще нет приложения, к которому его можно было бы прикрепить.
Есть ли способ ссылаться на родительский каталог для выполнения расширений?
Отредактируйте, чтобы уточнить: решение ApplicationProxy не работает из-за выделенного жирным шрифтом текста выше. Прямо сейчас, как обходной путь, мы просто не проверяем \ dir \ application.cfc в SVN, чтобы каждый разработчик мог сохранить версию, расширяющую его / ее собственный корневой файл application.cfc. Очевидно, это не идеально.





У Шона Корфилда есть запись в блоге, объясняющая, как расширить корневой 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
Все эти приложения представляют собой отдельные отдельные приложения, между которыми ничего не разделяется.
Если на каком-либо из этих отдельных сайтов должны быть субприложения, тогда должен быть ApplicationProxy.cfc помимо Мастера,
e.g.
/site1/ApplicationProxy.cfc
/site2/ApplicationProxy.cfc
Затем для каждого субприложения у вас есть то, которое расширяет прокси:
e.g.
/site1/subA/Application.cfc
/site1/subB/Application.cfc
/site2/subA/Application.cfc
Soldernal, если корень сайта не является веб-корнем, вам потребуется сопоставление с корнем сайта. Если ваше имя отображения - foo, вы расширяете "foo.application".
Похоже, я снова столкнулся с исходной проблемой. Если я создам сопоставление для foo с \ devsite1 \, тогда \ devsite2 \ dir \ application.cfc расширит \ devsite1 \ application.cfc
Не создавайте сопоставление с /devsite1. Создайте отображение /common и обратитесь к common.ApplicationProxy как в /devsite1/application.cfc, так и в /devsite2/dir/application.cfc.
Я не слежу за тобой. Разве это не означает, что файлы /dir/application.cfc расширяют обычный application.cfc? Все дело в том, что я могу редактировать \application.cfc, не беспокоясь о том, что при этом сломаю другие сайты разработчиков.
Я просто отредактировал ответ, чтобы попытаться объяснить, как это будет работать для нескольких сайтов с их собственными суб-приложениями, хотя я все еще не уверен, понимаю ли я, чего вы пытаетесь достичь.
Я считаю, что вам следует изменить свойство name на DisplayName, Name не является свойством тега cfcomponent. По крайней мере, согласно документации Adobe. Может я что то упустил?
Код был просто скопирован из указанной ссылки, но вы правы, что имя не является допустимым атрибутом (я думаю, что это пережиток CFMX6 / 7 дней). Однако отображаемое имя также бесполезно, даже если это поддерживаемый атрибут, в нем нет необходимости.
У меня работает следующий код. Однако я заметил одну вещь: кажется, что 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>
Я знаю, что это старая тема, но я нашел способ сделать это (который, похоже, работал в моем тестировании) без использования сопоставлений администратора CF.
Вы можете сделать это, добавив сопоставление для каждого приложения в свой дочерний Application.cfc, используя расширенный относительный путь:
<cfcomponent extends = "cms.Application" output = "false">
<cfset this.mappings["/cms"] = expandPath(getDirectoryFromPath(getCurrentTemplatePath()) & "../../../../")>
<cflog text = "#getMetadata(this).extends.path#">
</cfcomponent>
Да, это кажется немного взломанным, но, похоже, работает.
Похоже, у меня это не работает. Не могли бы вы объяснить это дальше и, возможно, указать, какую версию ColdFusion вы используете? Кажется, что сопоставление не будет определено до тех пор, пока Application.cfc не начнет обрабатываться, что не может произойти, потому что сопоставление требуется для того, чтобы он прошел за 1-ю строку.
Разве это не предполагает, что корень сайта является веб-корнем? Похоже, у меня это не работает.