Как заставить оценку cfif, хранящегося в строке? - PullRequest
0 голосов
/ 21 декабря 2010

Я пытаюсь сохранить код Coldfusion в базе данных, которая будет использоваться для темы cfmail.Сохраненный код выглядит следующим образом:

"RE: <cfif myData.general.legalName NEQ """">  {{dotlegalname}}<cfelse>{{docketLegalName}}</cfif>,    
DOT## {{dot}}, Docket ##(s)   {{docketString}}" 

При извлечении строки из базы данных я использую cfsavecontent, чтобы попытаться ее оценить.

<cfsavecontent variable="subject">
 <cfoutput>#myData.email.subject#</cfoutput>
</cfsavecontent>

Я также пытался

<cfsavecontent variable="subject">
     <cfoutput>#evaluate(myData.email.subject)#</cfoutput>
</cfsavecontent>

а потом я заменяю все {{}} с соответствующими значениями.

1011 * тем не менее, тема письма упорно отказывается содержать оцененную Cfif, и вместо того, чтобы показывать на Cfif, как будто этобыли строки.

Есть идеи?

Ответы [ 10 ]

3 голосов
/ 21 декабря 2010

Единственный способ динамически оценить код, который вы создаете во время выполнения, - это записать его в файл и затем выполнить.

Самый простой способ - написать страницу .cfm в виртуальной файловой системе (возможно, имя файла будет после UUID, поэтому он уникален), а затем указать, где вам нужно запустить содержимое.

Обычно я бы не рекомендовал создавать код во время выполнения, но это может быть самым элегантным решением в некоторых случаях.

В качестве альтернативы, вместо хранения кода CFML в базе данных, у вас есть набор файлов шаблонов электронной почты CFML, которые хранятся в каталоге на вашем сервере, и в вашей базе данных вы просто записываете, какой шаблон должен быть включен либо через cfinclude или cfmodule.

3 голосов
/ 21 декабря 2010

Вы не можете динамически оценивать CFML, хранящийся в базе данных, без предварительной записи его в файл и последующего использования <cfinclude> для его включения.

2 голосов
/ 30 сентября 2011

почему бы просто не использовать что-то вроде усов?

http://mustache.github.com/ https://github.com/pmcelhaney/Mustache.cfc

у него есть возможность не только выполнять ту логику, которая вам нужна в вашем скриптединамически.я бы действительно посоветовал вам проверить проект и, возможно, даже улучшить его и внести в него свой вклад.

ОН, и просто для того, чтобы иметь возможность оказаться в мыльной корзине: я годами писал в Adobe, говоря, что нам нужна возможностьдинамически анализировать и визуализировать CFML.К сожалению, мои крики были проигнорированы.возможно, если больше людей будут жаловаться на то, что эту функцию нужно добавить, она получит внимание, которого заслуживает.

2 голосов
/ 21 декабря 2010

В дополнение к ответу Марка приведен код псевдо:

<cfset fileName = createUUID() & ".cfm">
<cfset fileWrite( fileName, [CODE_FROM_DB]>
<cfinclude template="#fileName#">
<cfset fileDelete( fileName )>

Я использовал такой код раньше без проблем. Все в виртуальной файловой системе летит, поскольку все это работает в оперативной памяти. Для лучшей практики не забудьте удалить созданные файлы;)

2 голосов
/ 21 декабря 2010

Если вы абсолютно должны это сделать, посмотрите на функциюvalu (). По сути, это запускает новый поток CF, компилирует переданную ему строку, запускает ее и возвращает результат.

Если это вообще возможно, я бы попытался найти способ перенести вашу логику в текущий выполняемый файл, а не в строку из базы данных. Я предполагаю, что вы извлекаете данные на основе какой-то строки, которую вы уже создали, поэтому вы можете добавить к ней что-нибудь, поэтому вы ищите subjectDotLegal и subjectDocketLegal или что-то подобное.

Помните, методубы () медленный, уродливый и может быть опасным (он будет запускать все, что передано ему!). Если есть способ обойти это, я предлагаю вам использовать его.

0 голосов
/ 25 апреля 2013

Вот как я сохранил свой верхний и нижний колонтитулы для всех страниц в записи. Этот код может идти вверху каждой страницы. Но он у меня есть в APPLICATION.cfm, и, похоже, он отлично работает.

Ключом здесь не является использование знаков # pound # в ваших выражениях. Пользователь [квадратные скобки]. Код выберет их, оценит и вернет результат обратно в шаблон.

Он заменит число 0, если не может оценить выражение как средство обработки ошибок.

<CFSET FooterID=1234>  <!-- ID of the record you want to use -->
<CFQUERY NAME="StoredHeader" Datasource="DS1">
  Select Body from templates where id=#FooterID#
</CFQUERY>

<CFSET Parse=StoredHeader.Body>

<CFLOOP CONDITION="FindNoCase('[',Parse,1) GT 0">
    <CFSET STB=FindNoCase('[',Parse,1)>
    <CFSET ENB=FindNoCase(']',Parse,1)>
    <CFIF ENB-STB GT 0>
    <CFSET BracketExp=Mid(Parse,STB+1,ENB-1-STB)>
            <CFTRY>
                <CFSET BracketValue=Evaluate(BracketExp)>
                <CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']',Evaluate(#BracketExp#))>                
                <cfcatch type="any">
                    <div>'Using ZERO 0 for missing <cfoutput>#BracketExp#' </cfoutput> </div>
                    <CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']','0')>
                </cfcatch>
            </CFTRY>        
    </CFIF>
</CFLOOP>
<CFSET Footer=Parse>

<cfoutput>FOOTER</cfoutput>
0 голосов
/ 27 марта 2013

Есть лучший способ, а именно использование в памяти файлов.Таким образом, у вас нет ввода-вывода на диске и, следовательно, намного быстрее:

Для тегов, которые принимают логический путь, определите отображение в Администраторе.Выполните страницы CFM в памяти, используя тег cfinclude:

Создайте отображение для ram: ///, чтобы его можно было использовать в тегах.В этом примере / inmemory - это отображение, которое указывает на ram: ///.

Для тегов, которые принимают абсолютный путь, укажите синтаксис, как указано в следующем примере:

Вы также можете удалить файл из оперативной памяти и удалить действие.

0 голосов
/ 30 сентября 2011

В OpenBlueDragon есть функция рендер , которая может сделать это.

Вы можете имитировать эту функцию в Railo, создав собственную встроенную функцию, которая сохраняет файл в ОЗУ, а затем включает его, используя следующий код:

<cffunction name="render" output="Yes" returntype="string"><!--- 
       ---><cfargument name="Code" required="Yes" type="string"><!--- 
       ---><cfset local.mapping = {'/render_ram_resource':'ram://'}><!--- 
       ---><cfapplication action="update" mappings="#local.mapping#"><!--- 
       ---><cfset local.fileName = "/render_ram_resource/_render_" & 
createUUID() & ".cfm"><!--- 
       ---><cffile action="WRITE" file="#fileName#" 
output="#arguments.Code#"><!--- 
       ---><cfinclude template="#fileName#"><!--- 
       ---><cffile action="DELETE" file="#fileName#"><!--- 
---></cffunction> 

(Это выглядит необычно, потому что нужно разрешить вывод, но не допустить лишних пробелов, отсюда и все комментарии. К сожалению, подсветка синтаксиса SO, похоже, смущает их.)

Если вам нужно ACF-совместимое решение, вам нужно использовать обычную файловую систему и предварительно созданное сопоставление. (Ну, в ACF9 и выше вы можете использовать виртуальную файловую систему RAM, но на самом деле вы не можете создавать сопоставления на лету, как это.)

0 голосов
/ 21 декабря 2010

В качестве примера: предположим, code.txt - это текстовый файл, который содержит следующее (просто для упрощения моделирования CFML, хранящегося в БД): <cfoutput>#now()#</cfoutput>

Будет работать следующий код:

<cfset q = queryNew("code") />
<cfset queryAddRow(q,1) />
<cfset querySetCell(q, "code", fileRead(expandPath('code.txt')), 1) />
<cfdump var="#q#">
<cfset newCodeFile = expandPath('dynamic.cfm') />
<cfset fileWrite(newCodeFile, q.code[1]) />
<cfinclude template="dynamic.cfm" />
0 голосов
/ 21 декабря 2010

Я бы попробовал встроенную функцию QuoteName .

...