Mandrill in ColdFusion - coldfusion

I am trying to use Mandrill with ColdFusion 6.1. ColdFusion is not one of Mandrell's supported languages. I am pretty sure I need to use cfhttp and Post. Are there any resources or example to help me along.

I'm surprised that no one has released a CFC yet (and had previously tweeted about it), but the API is pretty simple. For example, you can communicate to Mandrill directly using javascript.
https://bitbucket.org/mailchimp/mandrill-api-js/
Mandril uses a restful API. Here's a link to the full documentation:
https://mandrillapp.com/api/docs/
In order to send a message, you need to POST a JSON packet using your own API key. (In the demo link, you can modify the JSON and click the "try it" button to send a test message.)
https://mandrillapp.com/api/docs/messages.JSON.html#method-send
You may need to manually generate your own JSON as ColdFusion tends to convert numbers and boolean values into strings.

You can simply use a cfmail tag and set the smtp username and password to the values provided by Mandrill. They have a full set of documentation on using SMTP with Mandrill.
Here's some sample code:
<cfmail
from="you#you.com"
subject="Your subject line"
to="him#him.com"
type="HTML"
server="smtp.mandrillapp.com"
port="587"
username="yourusername"
password="yourkey"
>
<cfmailparam name="X-MC-Tags" value="Some tag to track in Mandrill" />
<cfmailparam name="X-MC-Track" value="opens,clicks" />
<cfmailparam name="X-MC-Autotext" value="false" />
<html>
<head>
<style type="text/css">
</style>
</head>
<body>
A whole lot of body content goes here.
</body>
</html>
</cfmail>

Related

ColdFusion10 CFDocument debug output

Is there a way to capture the complete HTML code from CFDocument before it generates the actual Document/PDF (for debugging)?
The tag itself doesn't seem to support it.
What works partially is storing the separate parts of the HTML via cfsavecontent but I can't capture the whole thing at once:
<cfsavecontent variable="test123">
<style type="text/css" media="screen">
<!-- Style based on paperSize-->
<cfoutput>
#request.paperSize.css#
</cfoutput>
</style>
</cfsavecontent>
<cfdump var="#test123#" output="#expandPath('./test123.html')#" format="html">
So I thought of two ways:
Raising the log level of the underlying PDF component or some other way to revealing the code from there? (Is it iText?)
"Escaping" the HTML code so I can read the HTML in the PDF (no idea how to do this in CF)
Any ideas how I could go about this?

Error using cfhttp to retrieve page contents from bitly url

I am using cfhttp (Lucee Server) to scrape page contents from a url in the following manner:
<cfhttp url="#libs.originalAdPage#" method="GET" />
I then place this content in a div on my page.
This code has been working for a long time.
I have a need to report on the url's that have been scraped for their content and that information is placed into another website form that is not in my control. I decided to convert the url's to shortened bitly url's. I built the process into the page to create a bitly link and return that url to replace the existing url.
If i use the page with a shortened url from linkedin the page is scraped and displayed correctly in the div.
<cfhttp url="http://bit.ly/1NPhPgc" method="GET" />
But if I do an identical cfhttp call to a Indeed.com page shorted to a bitly URL I get a connection failure error.
<cfhttp url="http://bit.ly/1RQvlim" method="GET" />[![cfdump of connection failure][1]][1]
If I open this URL directly in the browser the page is displayed correctly.
Any ideas would be greatly appreciated.
Thanks,
Michael
I don't have access to a Lucee server to test with, however cfhttp on a ColdFusion server works fine for me for both of those bitly URLs. cfhttp follows the redirect and the FileContent contains the indeed.com page as would be expected.
Have you verified what happens with the Bitly Indeed URL if you prevent cfhttp from automatically following the redirects so that you can debug and follow the redirects manually? ie
<cftry>
<cfhttp url="http://bit.ly/1RQvlim" method="GET" redirect="no" />
<cfdump var="#cfhttp.responseHeader#" />
<cfhttp url="#cfhttp.responseHeader.Location#" method="GET" />
<cfdump var="#cfhttp#" label="cfhttp2" />
<cfcatch>
<cfdump var="#cfcatch#" label="cfcatch" />
</cfcatch>
</cftry>
Indeed.com do pay attention to crawlers and user agents - just see their robots.txt for evidence of this.
Do you have access to a different server to test with in case there is something specific to Lucee's cfhttp implementation or to your IP address (eg blacklisted due to all the scraping)?
Have you tried tweaking the cfhttp useragent and/or any other headers as per How to emulate a real http request via cfhttp?

How to structure a master page with coldfusion?

I have a small coldfusion section of our site that all uses similar js and css files and page structure. The code is currently repeated for each file, and I'd like to factor it out and set something up using a master page and templates.
Master.cfm page:
<!--- Master template, includes all necessary js and css files.
Expects following variables to be defined:
- pageName - name of the file to be loaded as the body of the page
- title - text to be used as the title of the page and as the header text in the header bar --->
<cfinclude template="_lockedPage.cfm" />
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>#title#</title>
... all script and css links here ...
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jquery.mobile-1.3.2.js"></script>
... etc ...
</head>
<body>
<div data-role="page">
<div class="headerDiv" data-role="header" data-theme="b" data-position="fixed">
<a id="backButton" data-role="button" data-direction="reverse" data-rel="back" data-icon="arrow-l" data-iconpos="left" data-theme="a">Back</a>
<h1><cfoutput>#title#</cfoutput></h1>
Home
</div>
<div data-role="content" class="container">
<cfinclude template="#pageName#.cfm" />
</div>
</div>
</body>
</html>
Then a page example would be something like this. CustomerSearch.cfm:
<cfscript>
title = "Customer Search";
pageName = "_customer-search";
include "Master.cfm";
</cfscript>
And then I would need a _customer-search.cfm page that would include all the body content for the page.
This means that I would need 2 files for every page that we currently have - the outer page that defines the variable and includes the master page, and the template page that has the individual page content.
Is this a good logical structure? Is there anyway to improve it?
You have the right idea, but I think you'll end up with a lot of unnecessary files. You could instead create a header.cfm and a footer.cfm that contain your global HTML. Each page would include those files and the content would be written between.
<cfset title = "Customer Search">
<cfinclude template="global_header.cfm">
<!--- This will be the content of your page. --->
<cfinclude template="global_footer.cfm">
This file would be named customer_search.cfm. Anytime you update the header or footer, it's a global change.
If you have a lot of business logic and query code that needs to exist on multiple pages, you might look into using an MVC framework to help you organize and reuse code. I prefer ColdBox (try ColdBox Lite), but many people use Framework/1.
I found that using custom tags was another simple solution and in my opinion a better solution to creating a separate header.cfm and footer.cfm.
In master.cfm:
<cfif ThisTag.ExecutionMode EQ 'start'>
[HEADER]
<cfelse>
[FOOTER]
<cfif>
In each content page:
<cf_master>
[CONTENT GOES HERE]
</cf_master>
If you'd like to pass in variables to the master page simply add it as an attribute to the opening tag:
<cf_master Title="Content Title">
And make sure the attribute is specified in the master file:
<cfparam name="Attributes.Title" default=""/>
<head>
<title><cfoutput>#Attributes.Title#</cfoutput></title>
</head>
The key for me was understanding the ThisTag.ExectuionMode. If you use custom tags you can either use just one tag or use an opening and closing tag. If you use an opening and closing tag then you can choose to include some content in the opening tag <cf_master>, and other content in the closing tag </cf_master>. That is why you need the if/else condition in master.cfm. In this case it is useful because then you can include a HEADER in the opening tag and a FOOTER in the closing tag.
Also, in case this isn't obvious, when you call your custom tag, it should match the name of the file where the code is stored. In my case <cf_master> matches master.cfm.
I used this page as a tutorial for custom tags: https://www.petefreitag.com/item/64.cfm
The Application.cfc can be a great use for common page design. Basically have one template and inject the pages generated content. Dan Bracuk commented in the other solution about using the Application.cfc onRequestStart() and onRequestEnd() methods but I use it slightly differently. Here is my general setup:
Application.cfc
// This is <cfscript> but it could be regular CFML too
component {
public function onRequest( required string targetPage ) {
// Capture/buffer the requested pages output
savecontent variable='LOCAL.output' {
include ARGUMENTS.targetPage;
}
// Use the output as the page content
// if the page did not specify content
param string REQUEST.content = LOCAL.output;
// Inject the design template
// which should output the page content somewhere
include '/path/to/template.cfm';
}
}
template.cfm
<!DOCTYPE html>
<cfparam name="REQUEST.title" type="string" /><!--- required --->
<cfparam name="REQUEST.head" type="string" default="" />
<cfparam name="REQUEST.content" type="string" /><!--- required --->
<html>
<head>
<title><cfoutput>#REQUEST.title#</cfoutput></title>
<link rel="stylesheet" href="path/to/common.css" />
<script src="path/to/common.js"></script>
<cfoutput>#REQUEST.head#</cfoutput>
</head>
<body>
<header>...</header>
<cfoutput>#REQUEST.content#</cfoutput>
<footer>...</footer>
</body>
</html>
each-page.cfm
<cfset REQUEST.title = "My Page Title" />
<cfsavecontent variable="REQUEST.head">
<!-- page specific head elements here -->
</cfsavecontent>
<!-- Regular page code/HTML output here -->
<!--- or you could use another <cfsavecontent> block --->
<!--- to save specific output sections --->
<p>Hello World</p>
This way allows you to keep the template all within one file which is much easier when designing it in a WYSIWYG manor. It also allows each page to set variables used in the design template, since the requested page is executed before the design template is included.
And, there is no need to <cfinclude> templates on each page since Application.cfc onRequest() will get called for ALL pages by default. If there are .cfm pages which should NOT include the design template, such as PDF output, then you'll need to add some logic to just dump the output and not include the design template.

Non-Authenticated FreeMarker page in alfresco share

i have create a new page in alfresco share but the page cannot be displayed without login! how can i make this page enabled without login.
my file in "/alfresco/templates/blog/demo/custom-viewer.ftl".
and this file contains "custom-viewer.ftl":
<#include "include/alfresco-template.ftl" />
<#templateHeader>
<#script type="text/javascript" src="${url.context}/res/modules/documentlibrary/doclib-actions.js" group="document-details"/>
<#link rel="stylesheet" type="text/css" href="${url.context}/res/components/document- details/document-details-panel.css" group="document-details"/>
<#templateHtmlEditorAssets />
</#>
<#templateBody>
<#region id="web-preview" scope="template"/>
</#>
<#templateFooter>
</#>
and the file in "/alfresco/site-data/pages/custom-viewer.xml".
and this file contains "custom-viewer.xml":
<?xml version='1.0' encoding='UTF-8'?>
<page>
<title>Custom Viewer</title>
<template-instance>custom-viewer</template-instance>
<authentication>none</authentication>
</page>
the page is work correctly but i need it to work without login? any help please?!!
The thing is probably not your page which needs login but the components it's including.
I'm seeing component regioun web-preview, if this defaults to the default web-preview: site-webscripts\org\alfresco\components\preview\web-preview.get.desc.xml
Then this components needs authentication, there is no <authentication> tag, so it defaults to user.
If you delete that <#region....> tag, you'll see the page.

CFMail not sending to email address that has a single quote in it

How can I use cfmail to send an email to an address that has a single quote in it? For example:
firstname.o'flanagan#example.com
For some reason I can't get an email sent to that address no matter what I do. Here's the cfmail tag code I'm using. I've tested all the variables and they're all defined:
<cfmail from="#getEmail.from_email#"
to="#email#"
subject="#getEmail.subject#"
type="HTML"
cc="#cc_email#"
bcc="#attributes.bcc_email#"
charset="UTF-8">
Am I missing something? Thanks for the help.
Did you try
<cfmail from="#getEmail.from_email#"
to="#preserveSingleQuotes(email)#"
subject="#getEmail.subject#" type="HTML"
cc="#cc_email#" bcc="#attributes.bcc_email#" charset="UTF-8">
using the PreserveSingleQuotes should allow you to send to that address. Unfortunately using a single quote is valid in an email.