2009-12-09 2 views
4

У моего клиента есть таблица базы данных тел электронной почты, которая отправляется клиентам в определенное время. Текст для электронных писем содержит выражения ColdFusion, такие как Dear # firstName # и т. Д. Эти электронные письма - это HTML - они также содержат всевозможные разметки HTML. То, что я хотел бы сделать, это прочитать этот текст из базы данных в строку, а затем обработать ColdFusion Evaluate(), чтобы разрешить переменные. Когда я это делаю, Evaluate() выдает исключение, потому что ему не нравится разметка HTML (я также пытался фильтровать строку через HTMLEditFormat() в качестве промежуточного шага для усмешек, но ей не нравились сущности) ,Устранение переменных внутри строки Coldfusion

Мой предшественник решил эту проблему, написав текст электронной почты в файл, а затем включив его. Оно работает. Это кажется действительно взломанным. Есть ли более элегантный способ справиться с этим, используя что-то вроде Evaluate, которое я не вижу?

+0

Я хотел бы указать, что запись этого в FS или использование Evaluate() позволяет выполнять ЛЮБЫЕ и ВСЕ коды. Это может привести к проблемам безопасности, если они не будут обрабатываться с максимальной осторожностью. Я бы пошел с заменой переменной kevink. –

+0

Согласен с Бен. Evaluate отлично работает, пока вы не получите столько запросов в секунду, что CF дает ошибки. Заменить - это лучший способ зайти так далеко, что я нашел. –

ответ

9

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

Dear {{name}}, Thanks for trying {{product_name}}. Etc... 

И тогда вы можете просто:

<cfset str = ReplaceNoCase(str, "{{name}}", name, "ALL") /> 

И если вы хотите, чтобы получить новые идеи вы могли бы просто написать метод, чтобы обернуть это:

<cffunction name="fillInTemplate" access="public" returntype="string" output="false"> 
    <cfargument name="map" type="struct" required="true" /> 
    <cfargument name="template" type="string" required="true" /> 

    <cfset var str = arguments.template /> 
    <cfset var k = "" /> 

    <cfloop list="#StructKeyList(arguments.map)#" index="k"> 
     <cfset str = ReplaceNoCase(str, "{{#k#}}", arguments.map[k], "ALL") /> 
    </cfloop> 

    <cfreturn str /> 
</cffunction> 

И использовать его так:

<cfset map = { name : "John", product : "SpecialWidget" } /> 
<cfset filledInTemplate = fillInTemplate(map, someTemplate) /> 
+1

Это получает кивок для полного кода образца, хотя вместо Replace мне пришлось использовать REReplaceNoCase, поскольку Replace учитывает регистр и CF преобразует все ключи элементов структуры в верхний регистр. – DaveBurns

+1

Имеет смысл. Я обновил для использования ReplaceNoCase вместо REReplaceNoCase, потому что вам не нужны регулярные выражения, но я полагаю, вы могли бы использовать их, если хотите. – Bialecki

+0

Интересно. Я использую CF7, и я искал ReplaceNoCase, но он не указан в моей книге CF7 WACK, и у него нет интерактивной справки в Adobe, если вы не посмотрите на CF8 и выше. Я предположил, что он добавлен в CF8, но я вижу, что он используется в примере кода для CF6. Итак, не уверен, что с этим делать. – DaveBurns

2

CF 7+: Вы можете использовать регулярное выражение, REReplace()?

CF 9: используйте Virtual File System

+0

Henry - Спасибо, я забыл упомянуть, что я на CF7. Я не вижу, как использовать REReplace для замены переменных. Есть что-то, чего я не вижу в документе? – DaveBurns

+0

вы можете делать почти все с регулярным выражением! :) Ну, просто выкиньте имя переменной внутри # varName #, а затем вызовите evalulate (varName) и замените «# varName #» на результат с оценкой? – Henry

+0

или ...цикл через каждый символ в строке, как входной поток, когда u встречает знак #, останавливает вывод в выходной поток, пока u не ударит другой знак #, не оценит записанную строку и не добавит ее в выходной поток. :) – Henry

9

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

Как о чем-то вроде этого (не проверено)

<cfset var BaseTemplate = "... lots of html with embedded tokens"> 

<cfloop (on whatever)> 

    <cfset LoopTemplate = replace(BaseTemplate, "#firstName#", myvarforFirstName, "All"> 
    <cfset LoopTemplate = replace(LoopTemplate, "#lastName#", myvarforLastName, "All"> 
    <cfset LoopTemplate = replace(LoopTemplate, "#address#", myvarforAddress, "All"> 

</cfloop> 

Просто обработайте html-блок как простую строку.

+1

Yup. Обычно я заполняю шаблоны электронной почты динамическими переменными, просто ключевые слова, заключенные в другие% символов%. – Sergii

+0

Я сделал аналогичные, но избегал хэш-меток, чтобы разграничивать переменные, особенно потому, что он играет хаос при чтении файла. Обычно мне нравится прикладывать свои переменные к [[скобки]]. – ale

+0

Похоже, что он обрабатывал устаревший код с синтаксисом # fieldname #, уже встроенным в его «шаблоны». Если вы проектируете его с нуля, я согласен, что символ «#» будет ужасным выбором. – kevink

-2

Если переменная находится в структуре, что-то вроде сообщения формы, то вы можете использовать «StructFind». Он делает то же, что и вы. Я столкнулся с этой проблемой при обработке формы с динамическими входами.

Ex.

StructFind(FORM, 'WhatYouNeed') 
Смежные вопросы